about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-09-10 21:30:05 +0000
committerbors <bors@rust-lang.org>2025-09-10 21:30:05 +0000
commitf4665ab8368ad2e8a86d4390ae35c28bdd9561bb (patch)
tree301e5c15dcb2f6f64faf288a1fe2a1db1eaac790
parent565a9ca63e9df4b223fed0da01f15e578acfb538 (diff)
parentbb45ea3accf536e0915991c5d9120bab8a87541e (diff)
downloadrust-f4665ab8368ad2e8a86d4390ae35c28bdd9561bb.tar.gz
rust-f4665ab8368ad2e8a86d4390ae35c28bdd9561bb.zip
Auto merge of #146418 - matthiaskrgr:rollup-za0lrux, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - rust-lang/rust#145327 (std: make address resolution weirdness local to SGX)
 - rust-lang/rust#145879 (default auto traits: use default supertraits instead of `Self: Trait` bounds on associated items)
 - rust-lang/rust#146123 (Suggest examples of format specifiers in error messages)
 - rust-lang/rust#146311 (Minor symbol comment fixes.)
 - rust-lang/rust#146322 (Make Barrier RefUnwindSafe again)
 - rust-lang/rust#146327 (Add tests for deref on pin)
 - rust-lang/rust#146340 (Strip frontmatter in fewer places)
 - rust-lang/rust#146342 (Improve C-variadic error messages: part 2)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_ast/src/ast.rs95
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs15
-rw-r--r--compiler/rustc_ast_passes/messages.ftl19
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs55
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs50
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs27
-rw-r--r--compiler/rustc_builtin_macros/src/source_util.rs100
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs12
-rw-r--r--compiler/rustc_expand/src/module.rs9
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs11
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs144
-rw-r--r--compiler/rustc_interface/src/interface.rs22
-rw-r--r--compiler/rustc_interface/src/passes.rs17
-rw-r--r--compiler/rustc_lint/src/multiple_supertrait_upcastable.rs3
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs2
-rw-r--r--compiler/rustc_parse/src/lib.rs36
-rw-r--r--compiler/rustc_parse/src/parser/tests.rs7
-rw-r--r--compiler/rustc_span/src/symbol.rs13
-rw-r--r--library/std/src/io/error.rs3
-rw-r--r--library/std/src/net/mod.rs21
-rw-r--r--library/std/src/net/tcp.rs4
-rw-r--r--library/std/src/net/tcp/tests.rs2
-rw-r--r--library/std/src/net/udp.rs4
-rw-r--r--library/std/src/net/udp/tests.rs1
-rw-r--r--library/std/src/sync/barrier.rs4
-rw-r--r--library/std/src/sys/net/connection/mod.rs57
-rw-r--r--library/std/src/sys/net/connection/sgx.rs81
-rw-r--r--library/std/src/sys/net/connection/socket/mod.rs (renamed from library/std/src/sys/net/connection/socket.rs)108
-rw-r--r--library/std/src/sys/net/connection/uefi/mod.rs27
-rw-r--r--library/std/src/sys/net/connection/unsupported.rs10
-rw-r--r--library/std/src/sys/net/connection/wasip1.rs10
-rw-r--r--library/std/src/sys/net/connection/xous/tcplistener.rs26
-rw-r--r--library/std/src/sys/net/connection/xous/tcpstream.rs9
-rw-r--r--library/std/src/sys/net/connection/xous/udp.rs81
-rw-r--r--library/std/src/sys/net/mod.rs48
-rw-r--r--library/std/tests/sync/barrier.rs9
-rw-r--r--src/librustdoc/clean/render_macro_matchers.rs21
-rw-r--r--src/librustdoc/doctest/make.rs19
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs16
-rw-r--r--src/tools/rustfmt/src/parse/parser.rs14
-rw-r--r--tests/ui-fulldeps/auxiliary/parser.rs3
-rw-r--r--tests/ui-fulldeps/mod_dir_path_canonicalized.rs9
-rw-r--r--tests/ui/c-variadic/issue-86053-1.rs2
-rw-r--r--tests/ui/c-variadic/issue-86053-1.stderr4
-rw-r--r--tests/ui/c-variadic/not-async.rs7
-rw-r--r--tests/ui/c-variadic/not-async.stderr19
-rw-r--r--tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs12
-rw-r--r--tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr30
-rw-r--r--tests/ui/deref/pin-deref-const.rs79
-rw-r--r--tests/ui/deref/pin-deref-const.stderr51
-rw-r--r--tests/ui/deref/pin-deref.rs76
-rw-r--r--tests/ui/deref/pin-deref.stderr51
-rw-r--r--tests/ui/deref/pin-impl-deref.rs40
-rw-r--r--tests/ui/deref/pin-impl-deref.stderr85
-rw-r--r--tests/ui/feature-gates/feature-gate-c_variadic.rs8
-rw-r--r--tests/ui/feature-gates/feature-gate-c_variadic.stderr12
-rw-r--r--tests/ui/fmt/ifmt-bad-arg.stderr12
-rw-r--r--tests/ui/frontmatter/auxiliary/expr.rs4
-rw-r--r--tests/ui/frontmatter/auxiliary/makro.rs14
-rw-r--r--tests/ui/frontmatter/include-in-expr-ctxt.rs9
-rw-r--r--tests/ui/frontmatter/include-in-item-ctxt.rs10
-rw-r--r--tests/ui/frontmatter/included-frontmatter.rs12
-rw-r--r--tests/ui/frontmatter/proc-macro-observer.rs7
-rw-r--r--tests/ui/inference/note-and-explain-ReVar-124973.rs3
-rw-r--r--tests/ui/inference/note-and-explain-ReVar-124973.stderr8
-rw-r--r--tests/ui/macros/format-unused-lables.stderr15
-rw-r--r--tests/ui/mir/issue-83499-input-output-iteration-ice.rs5
-rw-r--r--tests/ui/mir/issue-83499-input-output-iteration-ice.stderr20
-rw-r--r--tests/ui/mir/unsized-extern-static.stderr5
-rw-r--r--tests/ui/parser/variadic-ffi-semantic-restrictions.rs37
-rw-r--r--tests/ui/parser/variadic-ffi-semantic-restrictions.stderr138
-rw-r--r--tests/ui/suggestions/missing-format-specifiers-issue-68293.rs35
-rw-r--r--tests/ui/suggestions/missing-format-specifiers-issue-68293.stderr49
-rw-r--r--tests/ui/trait-bounds/more_maybe_bounds.rs14
-rw-r--r--tests/ui/trait-bounds/more_maybe_bounds.stderr32
-rw-r--r--tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs31
-rw-r--r--tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs80
-rw-r--r--tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr66
-rw-r--r--tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs83
-rw-r--r--tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr80
81 files changed, 1612 insertions, 863 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 802a6fa3249..3e8fddd9954 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -2284,6 +2284,54 @@ pub struct FnSig {
     pub span: Span,
 }
 
+impl FnSig {
+    /// Return a span encompassing the header, or where to insert it if empty.
+    pub fn header_span(&self) -> Span {
+        match self.header.ext {
+            Extern::Implicit(span) | Extern::Explicit(_, span) => {
+                return self.span.with_hi(span.hi());
+            }
+            Extern::None => {}
+        }
+
+        match self.header.safety {
+            Safety::Unsafe(span) | Safety::Safe(span) => return self.span.with_hi(span.hi()),
+            Safety::Default => {}
+        };
+
+        if let Some(coroutine_kind) = self.header.coroutine_kind {
+            return self.span.with_hi(coroutine_kind.span().hi());
+        }
+
+        if let Const::Yes(span) = self.header.constness {
+            return self.span.with_hi(span.hi());
+        }
+
+        self.span.shrink_to_lo()
+    }
+
+    /// The span of the header's safety, or where to insert it if empty.
+    pub fn safety_span(&self) -> Span {
+        match self.header.safety {
+            Safety::Unsafe(span) | Safety::Safe(span) => span,
+            Safety::Default => {
+                // Insert after the `coroutine_kind` if available.
+                if let Some(extern_span) = self.header.ext.span() {
+                    return extern_span.shrink_to_lo();
+                }
+
+                // Insert right at the front of the signature.
+                self.header_span().shrink_to_hi()
+            }
+        }
+    }
+
+    /// The span of the header's extern, or where to insert it if empty.
+    pub fn extern_span(&self) -> Span {
+        self.header.ext.span().unwrap_or(self.safety_span().shrink_to_hi())
+    }
+}
+
 /// A constraint on an associated item.
 ///
 /// ### Examples
@@ -3526,6 +3574,13 @@ impl Extern {
             None => Extern::Implicit(span),
         }
     }
+
+    pub fn span(self) -> Option<Span> {
+        match self {
+            Extern::None => None,
+            Extern::Implicit(span) | Extern::Explicit(_, span) => Some(span),
+        }
+    }
 }
 
 /// A function header.
@@ -3534,12 +3589,12 @@ impl Extern {
 /// included in this struct (e.g., `async unsafe fn` or `const extern "C" fn`).
 #[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
 pub struct FnHeader {
-    /// Whether this is `unsafe`, or has a default safety.
-    pub safety: Safety,
-    /// Whether this is `async`, `gen`, or nothing.
-    pub coroutine_kind: Option<CoroutineKind>,
     /// The `const` keyword, if any
     pub constness: Const,
+    /// Whether this is `async`, `gen`, or nothing.
+    pub coroutine_kind: Option<CoroutineKind>,
+    /// Whether this is `unsafe`, or has a default safety.
+    pub safety: Safety,
     /// The `extern` keyword and corresponding ABI string, if any.
     pub ext: Extern,
 }
@@ -3553,38 +3608,6 @@ impl FnHeader {
             || matches!(constness, Const::Yes(_))
             || !matches!(ext, Extern::None)
     }
-
-    /// Return a span encompassing the header, or none if all options are default.
-    pub fn span(&self) -> Option<Span> {
-        fn append(a: &mut Option<Span>, b: Span) {
-            *a = match a {
-                None => Some(b),
-                Some(x) => Some(x.to(b)),
-            }
-        }
-
-        let mut full_span = None;
-
-        match self.safety {
-            Safety::Unsafe(span) | Safety::Safe(span) => append(&mut full_span, span),
-            Safety::Default => {}
-        };
-
-        if let Some(coroutine_kind) = self.coroutine_kind {
-            append(&mut full_span, coroutine_kind.span());
-        }
-
-        if let Const::Yes(span) = self.constness {
-            append(&mut full_span, span);
-        }
-
-        match self.ext {
-            Extern::Implicit(span) | Extern::Explicit(_, span) => append(&mut full_span, span),
-            Extern::None => {}
-        }
-
-        full_span
-    }
 }
 
 impl Default for FnHeader {
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 72f20a95ff0..4e2243e8787 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -2101,17 +2101,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 {
                     return;
                 }
-                if self.tcx.features().more_maybe_bounds() {
-                    return;
-                }
             }
             RelaxedBoundPolicy::Forbidden(reason) => {
-                if self.tcx.features().more_maybe_bounds() {
-                    return;
-                }
-
                 match reason {
                     RelaxedBoundForbiddenReason::TraitObjectTy => {
+                        if self.tcx.features().more_maybe_bounds() {
+                            return;
+                        }
+
                         self.dcx().span_err(
                             span,
                             "relaxed bounds are not permitted in trait object types",
@@ -2119,6 +2116,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         return;
                     }
                     RelaxedBoundForbiddenReason::SuperTrait => {
+                        if self.tcx.features().more_maybe_bounds() {
+                            return;
+                        }
+
                         let mut diag = self.dcx().struct_span_err(
                             span,
                             "relaxed bounds are not permitted in supertrait bounds",
diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl
index e5f1fcdc4b4..8dcf3e3aa38 100644
--- a/compiler/rustc_ast_passes/messages.ftl
+++ b/compiler/rustc_ast_passes/messages.ftl
@@ -57,8 +57,6 @@ ast_passes_auto_super_lifetime = auto traits cannot have super traits or lifetim
     .label = {ast_passes_auto_super_lifetime}
     .suggestion = remove the super traits or lifetime bounds
 
-ast_passes_bad_c_variadic = defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
-
 ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block
     .cannot_have = cannot have a body
     .invalid = the invalid body
@@ -66,6 +64,19 @@ ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block
 
 ast_passes_bound_in_context = bounds on `type`s in {$ctx} have no effect
 
+ast_passes_c_variadic_associated_function = associated functions cannot have a C variable argument list
+
+ast_passes_c_variadic_bad_extern = `...` is not supported for `extern "{$abi}"` functions
+    .label = `extern "{$abi}"` because of this
+    .help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
+
+ast_passes_c_variadic_must_be_unsafe =
+    functions with a C variable argument list must be unsafe
+    .suggestion = add the `unsafe` keyword to this definition
+
+ast_passes_c_variadic_no_extern = `...` is not supported for non-extern functions
+    .help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
+
 ast_passes_const_and_c_variadic = functions cannot be both `const` and C-variadic
     .const = `const` because of this
     .variadic = C-variadic because of this
@@ -84,6 +95,10 @@ ast_passes_const_without_body =
 ast_passes_constraint_on_negative_bound =
     associated type constraints not allowed on negative bounds
 
+ast_passes_coroutine_and_c_variadic = functions cannot be both `{$coroutine_kind}` and C-variadic
+    .const = `{$coroutine_kind}` because of this
+    .variadic = C-variadic because of this
+
 ast_passes_equality_in_where = equality constraints are not yet supported in `where` clauses
     .label = not supported
     .suggestion = if `{$ident}` is an associated type you're trying to set, use the associated type binding syntax
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 538918a890d..a6ef89b553d 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -492,7 +492,7 @@ impl<'a> AstValidator<'a> {
         }
 
         if !spans.is_empty() {
-            let header_span = sig.header.span().unwrap_or(sig.span.shrink_to_lo());
+            let header_span = sig.header_span();
             let suggestion_span = header_span.shrink_to_hi().to(sig.decl.output.span());
             let padding = if header_span.is_empty() { "" } else { " " };
 
@@ -685,22 +685,53 @@ impl<'a> AstValidator<'a> {
             });
         }
 
+        if let Some(coroutine_kind) = sig.header.coroutine_kind {
+            self.dcx().emit_err(errors::CoroutineAndCVariadic {
+                spans: vec![coroutine_kind.span(), variadic_param.span],
+                coroutine_kind: coroutine_kind.as_str(),
+                coroutine_span: coroutine_kind.span(),
+                variadic_span: variadic_param.span,
+            });
+        }
+
         match fn_ctxt {
             FnCtxt::Foreign => return,
             FnCtxt::Free => match sig.header.ext {
-                Extern::Explicit(StrLit { symbol_unescaped: sym::C, .. }, _)
-                | Extern::Explicit(StrLit { symbol_unescaped: sym::C_dash_unwind, .. }, _)
-                | Extern::Implicit(_)
-                    if matches!(sig.header.safety, Safety::Unsafe(_)) =>
-                {
-                    return;
+                Extern::Implicit(_) => {
+                    if !matches!(sig.header.safety, Safety::Unsafe(_)) {
+                        self.dcx().emit_err(errors::CVariadicMustBeUnsafe {
+                            span: variadic_param.span,
+                            unsafe_span: sig.safety_span(),
+                        });
+                    }
                 }
-                _ => {}
-            },
-            FnCtxt::Assoc(_) => {}
-        };
+                Extern::Explicit(StrLit { symbol_unescaped, .. }, _) => {
+                    if !matches!(symbol_unescaped, sym::C | sym::C_dash_unwind) {
+                        self.dcx().emit_err(errors::CVariadicBadExtern {
+                            span: variadic_param.span,
+                            abi: symbol_unescaped,
+                            extern_span: sig.extern_span(),
+                        });
+                    }
 
-        self.dcx().emit_err(errors::BadCVariadic { span: variadic_param.span });
+                    if !matches!(sig.header.safety, Safety::Unsafe(_)) {
+                        self.dcx().emit_err(errors::CVariadicMustBeUnsafe {
+                            span: variadic_param.span,
+                            unsafe_span: sig.safety_span(),
+                        });
+                    }
+                }
+                Extern::None => {
+                    let err = errors::CVariadicNoExtern { span: variadic_param.span };
+                    self.dcx().emit_err(err);
+                }
+            },
+            FnCtxt::Assoc(_) => {
+                // For now, C variable argument lists are unsupported in associated functions.
+                let err = errors::CVariadicAssociatedFunction { span: variadic_param.span };
+                self.dcx().emit_err(err);
+            }
+        }
     }
 
     fn check_item_named(&self, ident: Ident, kind: &str) {
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 476ed27a10e..ae805042c54 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -319,13 +319,47 @@ pub(crate) struct ExternItemAscii {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_bad_c_variadic)]
-pub(crate) struct BadCVariadic {
+#[diag(ast_passes_c_variadic_associated_function)]
+pub(crate) struct CVariadicAssociatedFunction {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
+#[diag(ast_passes_c_variadic_no_extern)]
+#[help]
+pub(crate) struct CVariadicNoExtern {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_c_variadic_must_be_unsafe)]
+pub(crate) struct CVariadicMustBeUnsafe {
+    #[primary_span]
+    pub span: Span,
+
+    #[suggestion(
+        ast_passes_suggestion,
+        applicability = "maybe-incorrect",
+        code = "unsafe ",
+        style = "verbose"
+    )]
+    pub unsafe_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(ast_passes_c_variadic_bad_extern)]
+#[help]
+pub(crate) struct CVariadicBadExtern {
+    #[primary_span]
+    pub span: Span,
+    pub abi: Symbol,
+    #[label]
+    pub extern_span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(ast_passes_item_underscore)]
 pub(crate) struct ItemUnderscore<'a> {
     #[primary_span]
@@ -660,6 +694,18 @@ pub(crate) struct ConstAndCVariadic {
 }
 
 #[derive(Diagnostic)]
+#[diag(ast_passes_coroutine_and_c_variadic)]
+pub(crate) struct CoroutineAndCVariadic {
+    #[primary_span]
+    pub spans: Vec<Span>,
+    pub coroutine_kind: &'static str,
+    #[label(ast_passes_const)]
+    pub coroutine_span: Span,
+    #[label(ast_passes_variadic)]
+    pub variadic_span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(ast_passes_pattern_in_foreign, code = E0130)]
 // FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::PatternsInFnsWithoutBody`)
 pub(crate) struct PatternInForeign {
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 6415e55e0b0..a6c8e7d29cc 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -565,6 +565,7 @@ fn make_format_args(
             &used,
             &args,
             &pieces,
+            &invalid_refs,
             detect_foreign_fmt,
             str_style,
             fmt_str,
@@ -645,6 +646,7 @@ fn report_missing_placeholders(
     used: &[bool],
     args: &FormatArguments,
     pieces: &[parse::Piece<'_>],
+    invalid_refs: &[(usize, Option<Span>, PositionUsedAs, FormatArgPositionKind)],
     detect_foreign_fmt: bool,
     str_style: Option<usize>,
     fmt_str: &str,
@@ -762,6 +764,31 @@ fn report_missing_placeholders(
         diag.span_label(fmt_span, "formatting specifier missing");
     }
 
+    if !found_foreign && invalid_refs.is_empty() {
+        // Show example if user didn't use any format specifiers
+        let show_example = used.iter().all(|used| !used);
+
+        if !show_example {
+            if unused.len() > 1 {
+                diag.note(format!("consider adding {} format specifiers", unused.len()));
+            }
+        } else {
+            let original_fmt_str =
+                if fmt_str.len() >= 1 { &fmt_str[..fmt_str.len() - 1] } else { "" };
+
+            let msg = if unused.len() == 1 {
+                "a format specifier".to_string()
+            } else {
+                format!("{} format specifiers", unused.len())
+            };
+
+            let sugg = format!("\"{}{}\"", original_fmt_str, "{}".repeat(unused.len()));
+            let msg = format!("format specifiers use curly braces, consider adding {msg}");
+
+            diag.span_suggestion_verbose(fmt_span, msg, sugg, Applicability::MaybeIncorrect);
+        }
+    }
+
     diag.emit();
 }
 
diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs
index 37bab5be542..11b868f81a9 100644
--- a/compiler/rustc_builtin_macros/src/source_util.rs
+++ b/compiler/rustc_builtin_macros/src/source_util.rs
@@ -1,3 +1,5 @@
+//! The implementation of built-in macros which relate to the file system.
+
 use std::path::{Path, PathBuf};
 use std::rc::Rc;
 use std::sync::Arc;
@@ -11,9 +13,11 @@ use rustc_expand::base::{
 };
 use rustc_expand::module::DirOwnership;
 use rustc_lint_defs::BuiltinLintDiag;
-use rustc_parse::parser::{ForceCollect, Parser};
+use rustc_parse::lexer::StripTokens;
+use rustc_parse::parser::ForceCollect;
 use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal, utf8_error};
 use rustc_session::lint::builtin::INCOMPLETE_INCLUDE;
+use rustc_session::parse::ParseSess;
 use rustc_span::source_map::SourceMap;
 use rustc_span::{ByteSymbol, Pos, Span, Symbol};
 use smallvec::SmallVec;
@@ -23,11 +27,7 @@ use crate::util::{
     check_zero_tts, get_single_str_from_tts, get_single_str_spanned_from_tts, parse_expr,
 };
 
-// These macros all relate to the file system; they either return
-// the column/row/filename of the expression, or they include
-// a given file into the current one.
-
-/// line!(): expands to the current line number
+/// Expand `line!()` to the current line number.
 pub(crate) fn expand_line(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
@@ -42,7 +42,7 @@ pub(crate) fn expand_line(
     ExpandResult::Ready(MacEager::expr(cx.expr_u32(topmost, loc.line as u32)))
 }
 
-/* column!(): expands to the current column number */
+/// Expand `column!()` to the current column number.
 pub(crate) fn expand_column(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
@@ -57,9 +57,7 @@ pub(crate) fn expand_column(
     ExpandResult::Ready(MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32 + 1)))
 }
 
-/// file!(): expands to the current filename */
-/// The source_file (`loc.file`) contains a bunch more information we could spit
-/// out if we wanted.
+/// Expand `file!()` to the current filename.
 pub(crate) fn expand_file(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
@@ -81,6 +79,7 @@ pub(crate) fn expand_file(
     )))
 }
 
+/// Expand `stringify!($input)`.
 pub(crate) fn expand_stringify(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
@@ -91,6 +90,7 @@ pub(crate) fn expand_stringify(
     ExpandResult::Ready(MacEager::expr(cx.expr_str(sp, Symbol::intern(&s))))
 }
 
+/// Expand `module_path!()` to (a textual representation of) the current module path.
 pub(crate) fn expand_mod(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
@@ -104,9 +104,9 @@ pub(crate) fn expand_mod(
     ExpandResult::Ready(MacEager::expr(cx.expr_str(sp, Symbol::intern(&string))))
 }
 
-/// include! : parse the given file as an expr
-/// This is generally a bad idea because it's going to behave
-/// unhygienically.
+/// Expand `include!($input)`.
+///
+/// This works in item and expression position. Notably, it doesn't work in pattern position.
 pub(crate) fn expand_include<'cx>(
     cx: &'cx mut ExtCtxt<'_>,
     sp: Span,
@@ -116,39 +116,48 @@ pub(crate) fn expand_include<'cx>(
     let ExpandResult::Ready(mac) = get_single_str_from_tts(cx, sp, tts, "include!") else {
         return ExpandResult::Retry(());
     };
-    let file = match mac {
-        Ok(file) => file,
+    let path = match mac {
+        Ok(path) => path,
         Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)),
     };
     // The file will be added to the code map by the parser
-    let file = match resolve_path(&cx.sess, file.as_str(), sp) {
-        Ok(f) => f,
+    let path = match resolve_path(&cx.sess, path.as_str(), sp) {
+        Ok(path) => path,
         Err(err) => {
             let guar = err.emit();
             return ExpandResult::Ready(DummyResult::any(sp, guar));
         }
     };
-    let p = unwrap_or_emit_fatal(new_parser_from_file(cx.psess(), &file, Some(sp)));
 
     // If in the included file we have e.g., `mod bar;`,
-    // then the path of `bar.rs` should be relative to the directory of `file`.
+    // then the path of `bar.rs` should be relative to the directory of `path`.
     // See https://github.com/rust-lang/rust/pull/69838/files#r395217057 for a discussion.
     // `MacroExpander::fully_expand_fragment` later restores, so "stack discipline" is maintained.
-    let dir_path = file.parent().unwrap_or(&file).to_owned();
+    let dir_path = path.parent().unwrap_or(&path).to_owned();
     cx.current_expansion.module = Rc::new(cx.current_expansion.module.with_dir_path(dir_path));
     cx.current_expansion.dir_ownership = DirOwnership::Owned { relative: None };
 
     struct ExpandInclude<'a> {
-        p: Parser<'a>,
+        psess: &'a ParseSess,
+        path: PathBuf,
         node_id: ast::NodeId,
+        span: Span,
     }
     impl<'a> MacResult for ExpandInclude<'a> {
-        fn make_expr(mut self: Box<ExpandInclude<'a>>) -> Option<Box<ast::Expr>> {
-            let expr = parse_expr(&mut self.p).ok()?;
-            if self.p.token != token::Eof {
-                self.p.psess.buffer_lint(
+        fn make_expr(self: Box<ExpandInclude<'a>>) -> Option<Box<ast::Expr>> {
+            let mut p = unwrap_or_emit_fatal(new_parser_from_file(
+                self.psess,
+                &self.path,
+                // Don't strip frontmatter for backward compatibility, `---` may be the start of a
+                // manifold negation. FIXME: Ideally, we wouldn't strip shebangs here either.
+                StripTokens::Shebang,
+                Some(self.span),
+            ));
+            let expr = parse_expr(&mut p).ok()?;
+            if p.token != token::Eof {
+                p.psess.buffer_lint(
                     INCOMPLETE_INCLUDE,
-                    self.p.token.span,
+                    p.token.span,
                     self.node_id,
                     BuiltinLintDiag::IncompleteInclude,
                 );
@@ -156,24 +165,27 @@ pub(crate) fn expand_include<'cx>(
             Some(expr)
         }
 
-        fn make_items(mut self: Box<ExpandInclude<'a>>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
+        fn make_items(self: Box<ExpandInclude<'a>>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
+            let mut p = unwrap_or_emit_fatal(new_parser_from_file(
+                self.psess,
+                &self.path,
+                StripTokens::ShebangAndFrontmatter,
+                Some(self.span),
+            ));
             let mut ret = SmallVec::new();
             loop {
-                match self.p.parse_item(ForceCollect::No) {
+                match p.parse_item(ForceCollect::No) {
                     Err(err) => {
                         err.emit();
                         break;
                     }
                     Ok(Some(item)) => ret.push(item),
                     Ok(None) => {
-                        if self.p.token != token::Eof {
-                            self.p
-                                .dcx()
-                                .create_err(errors::ExpectedItem {
-                                    span: self.p.token.span,
-                                    token: &pprust::token_to_string(&self.p.token),
-                                })
-                                .emit();
+                        if p.token != token::Eof {
+                            p.dcx().emit_err(errors::ExpectedItem {
+                                span: p.token.span,
+                                token: &pprust::token_to_string(&p.token),
+                            });
                         }
 
                         break;
@@ -184,10 +196,17 @@ pub(crate) fn expand_include<'cx>(
         }
     }
 
-    ExpandResult::Ready(Box::new(ExpandInclude { p, node_id: cx.current_expansion.lint_node_id }))
+    ExpandResult::Ready(Box::new(ExpandInclude {
+        psess: cx.psess(),
+        path,
+        node_id: cx.current_expansion.lint_node_id,
+        span: sp,
+    }))
 }
 
-/// `include_str!`: read the given file, insert it as a literal string expr
+/// Expand `include_str!($input)` to the content of the UTF-8-encoded file given by path `$input` as a string literal.
+///
+/// This works in expression, pattern and statement position.
 pub(crate) fn expand_include_str(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
@@ -206,6 +225,7 @@ pub(crate) fn expand_include_str(
         Ok((bytes, bsp)) => match std::str::from_utf8(&bytes) {
             Ok(src) => {
                 let interned_src = Symbol::intern(src);
+                // MacEager converts the expr into a pat if need be.
                 MacEager::expr(cx.expr_str(cx.with_def_site_ctxt(bsp), interned_src))
             }
             Err(utf8err) => {
@@ -218,6 +238,9 @@ pub(crate) fn expand_include_str(
     })
 }
 
+/// Expand `include_bytes!($input)` to the content of the file given by path `$input`.
+///
+/// This works in expression, pattern and statement position.
 pub(crate) fn expand_include_bytes(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
@@ -237,6 +260,7 @@ pub(crate) fn expand_include_bytes(
             // Don't care about getting the span for the raw bytes,
             // because the console can't really show them anyway.
             let expr = cx.expr(sp, ast::ExprKind::IncludedBytes(ByteSymbol::intern(&bytes)));
+            // MacEager converts the expr into a pat if need be.
             MacEager::expr(expr)
         }
         Err(dummy) => dummy,
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index f3ed6042105..d00a4c35834 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -51,6 +51,7 @@ use rustc_lint::unerased_lint_store;
 use rustc_metadata::creader::MetadataLoader;
 use rustc_metadata::locator;
 use rustc_middle::ty::TyCtxt;
+use rustc_parse::lexer::StripTokens;
 use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
 use rustc_session::config::{
     CG_OPTIONS, CrateType, ErrorOutputType, Input, OptionDesc, OutFileName, OutputType, Sysroot,
@@ -1288,10 +1289,15 @@ fn warn_on_confusing_output_filename_flag(
 
 fn parse_crate_attrs<'a>(sess: &'a Session) -> PResult<'a, ast::AttrVec> {
     let mut parser = unwrap_or_emit_fatal(match &sess.io.input {
-        Input::File(file) => new_parser_from_file(&sess.psess, file, None),
-        Input::Str { name, input } => {
-            new_parser_from_source_str(&sess.psess, name.clone(), input.clone())
+        Input::File(file) => {
+            new_parser_from_file(&sess.psess, file, StripTokens::ShebangAndFrontmatter, None)
         }
+        Input::Str { name, input } => new_parser_from_source_str(
+            &sess.psess,
+            name.clone(),
+            input.clone(),
+            StripTokens::ShebangAndFrontmatter,
+        ),
     });
     parser.parse_inner_attributes()
 }
diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs
index 19f3cdbc549..79ab3cab22c 100644
--- a/compiler/rustc_expand/src/module.rs
+++ b/compiler/rustc_expand/src/module.rs
@@ -4,6 +4,7 @@ use std::path::{self, Path, PathBuf};
 use rustc_ast::{AttrVec, Attribute, Inline, Item, ModSpans};
 use rustc_attr_parsing::validate_attr;
 use rustc_errors::{Diag, ErrorGuaranteed};
+use rustc_parse::lexer::StripTokens;
 use rustc_parse::{exp, new_parser_from_file, unwrap_or_emit_fatal};
 use rustc_session::Session;
 use rustc_session::parse::ParseSess;
@@ -67,8 +68,12 @@ pub(crate) fn parse_external_mod(
         }
 
         // Actually parse the external file as a module.
-        let mut parser =
-            unwrap_or_emit_fatal(new_parser_from_file(&sess.psess, &mp.file_path, Some(span)));
+        let mut parser = unwrap_or_emit_fatal(new_parser_from_file(
+            &sess.psess,
+            &mp.file_path,
+            StripTokens::ShebangAndFrontmatter,
+            Some(span),
+        ));
         let (inner_attrs, items, inner_span) =
             parser.parse_mod(exp!(Eof)).map_err(|err| ModError::ParserError(err))?;
         attrs.extend(inner_attrs);
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 5b1d3d6d35b..295573f4492 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -8,7 +8,7 @@ use rustc_ast::util::literal::escape_byte_str_symbol;
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{Diag, ErrorGuaranteed, MultiSpan, PResult};
-use rustc_parse::lexer::nfc_normalize;
+use rustc_parse::lexer::{StripTokens, nfc_normalize};
 use rustc_parse::parser::Parser;
 use rustc_parse::{exp, new_parser_from_source_str, source_str_to_stream, unwrap_or_emit_fatal};
 use rustc_proc_macro::bridge::{
@@ -485,8 +485,13 @@ impl server::FreeFunctions for Rustc<'_, '_> {
 
     fn literal_from_str(&mut self, s: &str) -> Result<Literal<Self::Span, Self::Symbol>, ()> {
         let name = FileName::proc_macro_source_code(s);
-        let mut parser =
-            unwrap_or_emit_fatal(new_parser_from_source_str(self.psess(), name, s.to_owned()));
+
+        let mut parser = unwrap_or_emit_fatal(new_parser_from_source_str(
+            self.psess(),
+            name,
+            s.to_owned(),
+            StripTokens::Nothing,
+        ));
 
         let first_span = parser.token.span.data();
         let minus_present = parser.eat(exp!(Minus));
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index b59dc4bd132..126ffabd448 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -174,12 +174,6 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
         }
     };
 
-    if let Node::TraitItem(item) = node {
-        let mut bounds = Vec::new();
-        icx.lowerer().add_default_trait_item_bounds(item, &mut bounds);
-        predicates.extend(bounds);
-    }
-
     let generics = tcx.generics_of(def_id);
 
     // Below we'll consider the bounds on the type parameters (including `Self`)
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 d14aef8ace4..99dc8e6e522 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -1,12 +1,13 @@
+use std::assert_matches::assert_matches;
 use std::ops::ControlFlow;
 
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_errors::codes::*;
 use rustc_errors::struct_span_code_err;
 use rustc_hir as hir;
+use rustc_hir::PolyTraitRef;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
-use rustc_hir::{AmbigArg, PolyTraitRef};
 use rustc_middle::bug;
 use rustc_middle::ty::{
     self as ty, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
@@ -230,122 +231,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         }
     }
 
-    /// Checks whether `Self: DefaultAutoTrait` bounds should be added on trait super bounds
-    /// or associated items.
-    ///
-    /// To keep backward compatibility with existing code, `experimental_default_bounds` bounds
-    /// should be added everywhere, including super bounds. However this causes a huge performance
-    /// costs. For optimization purposes instead of adding default supertraits, bounds
-    /// are added to the associated items:
-    ///
-    /// ```ignore(illustrative)
-    /// // Default bounds are generated in the following way:
-    /// trait Trait {
-    ///     fn foo(&self) where Self: Leak {}
-    /// }
-    ///
-    /// // instead of this:
-    /// trait Trait: Leak {
-    ///     fn foo(&self) {}
-    /// }
-    /// ```
-    /// It is not always possible to do this because of backward compatibility:
-    ///
-    /// ```ignore(illustrative)
-    /// pub trait Trait<Rhs = Self> {}
-    /// pub trait Trait1 : Trait {}
-    /// //~^ ERROR: `Rhs` requires `DefaultAutoTrait`, but `Self` is not `DefaultAutoTrait`
-    /// ```
-    ///
-    /// or:
-    ///
-    /// ```ignore(illustrative)
-    /// trait Trait {
-    ///     type Type where Self: Sized;
-    /// }
-    /// trait Trait2<T> : Trait<Type = T> {}
-    /// //~^ ERROR: `DefaultAutoTrait` required for `Trait2`, by implicit  `Self: DefaultAutoTrait` in `Trait::Type`
-    /// ```
-    ///
-    /// Therefore, `experimental_default_bounds` are still being added to supertraits if
-    /// the `SelfTyParam` or `AssocItemConstraint` were found in a trait header.
-    fn requires_default_supertraits(
-        &self,
-        hir_bounds: &'tcx [hir::GenericBound<'tcx>],
-        hir_generics: &'tcx hir::Generics<'tcx>,
-    ) -> bool {
-        struct TraitInfoCollector;
-
-        impl<'tcx> hir::intravisit::Visitor<'tcx> for TraitInfoCollector {
-            type Result = ControlFlow<()>;
-
-            fn visit_assoc_item_constraint(
-                &mut self,
-                _constraint: &'tcx hir::AssocItemConstraint<'tcx>,
-            ) -> Self::Result {
-                ControlFlow::Break(())
-            }
-
-            fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx, AmbigArg>) -> Self::Result {
-                if matches!(
-                    &t.kind,
-                    hir::TyKind::Path(hir::QPath::Resolved(
-                        _,
-                        hir::Path { res: hir::def::Res::SelfTyParam { .. }, .. },
-                    ))
-                ) {
-                    return ControlFlow::Break(());
-                }
-                hir::intravisit::walk_ty(self, t)
-            }
-        }
-
-        let mut found = false;
-        for bound in hir_bounds {
-            found |= hir::intravisit::walk_param_bound(&mut TraitInfoCollector, bound).is_break();
-        }
-        found |= hir::intravisit::walk_generics(&mut TraitInfoCollector, hir_generics).is_break();
-        found
-    }
-
-    /// Implicitly add `Self: DefaultAutoTrait` clauses on trait associated items if
-    /// they are not added as super trait bounds to the trait itself. See
-    /// `requires_default_supertraits` for more information.
-    pub(crate) fn add_default_trait_item_bounds(
-        &self,
-        trait_item: &hir::TraitItem<'tcx>,
-        bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
-    ) {
-        let tcx = self.tcx();
-        if !tcx.sess.opts.unstable_opts.experimental_default_bounds {
-            return;
-        }
-
-        let parent = tcx.local_parent(trait_item.hir_id().owner.def_id);
-        let hir::Node::Item(parent_trait) = tcx.hir_node_by_def_id(parent) else {
-            unreachable!();
-        };
-
-        let (trait_generics, trait_bounds) = match parent_trait.kind {
-            hir::ItemKind::Trait(_, _, _, _, generics, supertraits, _) => (generics, supertraits),
-            hir::ItemKind::TraitAlias(_, generics, supertraits) => (generics, supertraits),
-            _ => unreachable!(),
-        };
-
-        if !self.requires_default_supertraits(trait_bounds, trait_generics) {
-            let self_ty_where_predicates = (parent, trait_item.generics.predicates);
-            self.add_default_traits(
-                bounds,
-                tcx.types.self_param,
-                &[],
-                Some(self_ty_where_predicates),
-                trait_item.span,
-            );
-        }
-    }
-
-    /// Lazily sets `experimental_default_bounds` to true on trait super bounds.
-    /// See `requires_default_supertraits` for more information.
+    /// Adds `experimental_default_bounds` bounds to the supertrait bounds.
     pub(crate) fn add_default_super_traits(
         &self,
         trait_def_id: LocalDefId,
@@ -354,21 +240,21 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         hir_generics: &'tcx hir::Generics<'tcx>,
         span: Span,
     ) {
-        if !self.tcx().sess.opts.unstable_opts.experimental_default_bounds {
+        assert_matches!(self.tcx().def_kind(trait_def_id), DefKind::Trait | DefKind::TraitAlias);
+
+        // Supertraits for auto trait are unsound according to the unstable book:
+        // https://doc.rust-lang.org/beta/unstable-book/language-features/auto-traits.html#supertraits
+        if self.tcx().trait_is_auto(trait_def_id.to_def_id()) {
             return;
         }
 
-        assert!(matches!(self.tcx().def_kind(trait_def_id), DefKind::Trait | DefKind::TraitAlias));
-        if self.requires_default_supertraits(hir_bounds, hir_generics) {
-            let self_ty_where_predicates = (trait_def_id, hir_generics.predicates);
-            self.add_default_traits(
-                bounds,
-                self.tcx().types.self_param,
-                hir_bounds,
-                Some(self_ty_where_predicates),
-                span,
-            );
-        }
+        self.add_default_traits(
+            bounds,
+            self.tcx().types.self_param,
+            hir_bounds,
+            Some((trait_def_id, hir_generics.predicates)),
+            span,
+        );
     }
 
     pub(crate) fn add_default_traits(
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index 4c820b8877b..b52c5b4cd66 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -13,7 +13,8 @@ use rustc_lint::LintStore;
 use rustc_middle::ty;
 use rustc_middle::ty::CurrentGcx;
 use rustc_middle::util::Providers;
-use rustc_parse::new_parser_from_simple_source_str;
+use rustc_parse::lexer::StripTokens;
+use rustc_parse::new_parser_from_source_str;
 use rustc_parse::parser::attr::AllowLeadingUnsafe;
 use rustc_query_impl::QueryCtxt;
 use rustc_query_system::query::print_query_stack;
@@ -68,7 +69,8 @@ pub(crate) fn parse_cfg(dcx: DiagCtxtHandle<'_>, cfgs: Vec<String>) -> Cfg {
                 };
             }
 
-            match new_parser_from_simple_source_str(&psess, filename, s.to_string()) {
+            match new_parser_from_source_str(&psess, filename, s.to_string(), StripTokens::Nothing)
+            {
                 Ok(mut parser) => match parser.parse_meta_item(AllowLeadingUnsafe::No) {
                     Ok(meta_item) if parser.token == token::Eof => {
                         if meta_item.path.segments.len() != 1 {
@@ -166,13 +168,15 @@ pub(crate) fn parse_check_cfg(dcx: DiagCtxtHandle<'_>, specs: Vec<String>) -> Ch
             error!("expected `cfg(name, values(\"value1\", \"value2\", ... \"valueN\"))`")
         };
 
-        let mut parser = match new_parser_from_simple_source_str(&psess, filename, s.to_string()) {
-            Ok(parser) => parser,
-            Err(errs) => {
-                errs.into_iter().for_each(|err| err.cancel());
-                expected_error();
-            }
-        };
+        let mut parser =
+            match new_parser_from_source_str(&psess, filename, s.to_string(), StripTokens::Nothing)
+            {
+                Ok(parser) => parser,
+                Err(errs) => {
+                    errs.into_iter().for_each(|err| err.cancel());
+                    expected_error();
+                }
+            };
 
         let meta_item = match parser.parse_meta_item(AllowLeadingUnsafe::No) {
             Ok(meta_item) if parser.token == token::Eof => meta_item,
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 6d9751d7d4d..d39219bfd66 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -28,6 +28,7 @@ use rustc_middle::arena::Arena;
 use rustc_middle::dep_graph::DepsType;
 use rustc_middle::ty::{self, CurrentGcx, GlobalCtxt, RegisteredTools, TyCtxt};
 use rustc_middle::util::Providers;
+use rustc_parse::lexer::StripTokens;
 use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
 use rustc_passes::{abi_test, input_stats, layout_test};
 use rustc_resolve::{Resolver, ResolverOutputs};
@@ -52,10 +53,18 @@ pub fn parse<'a>(sess: &'a Session) -> ast::Crate {
     let mut krate = sess
         .time("parse_crate", || {
             let mut parser = unwrap_or_emit_fatal(match &sess.io.input {
-                Input::File(file) => new_parser_from_file(&sess.psess, file, None),
-                Input::Str { input, name } => {
-                    new_parser_from_source_str(&sess.psess, name.clone(), input.clone())
-                }
+                Input::File(file) => new_parser_from_file(
+                    &sess.psess,
+                    file,
+                    StripTokens::ShebangAndFrontmatter,
+                    None,
+                ),
+                Input::Str { input, name } => new_parser_from_source_str(
+                    &sess.psess,
+                    name.clone(),
+                    input.clone(),
+                    StripTokens::ShebangAndFrontmatter,
+                ),
             });
             parser.parse_crate_mod()
         })
diff --git a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs
index 5513c703f1d..93f067d0983 100644
--- a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs
+++ b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs
@@ -47,7 +47,8 @@ impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable {
                 .explicit_super_predicates_of(def_id)
                 .iter_identity_copied()
                 .filter_map(|(pred, _)| pred.as_trait_clause())
-                .filter(|pred| !cx.tcx.is_lang_item(pred.def_id(), hir::LangItem::MetaSized));
+                .filter(|pred| !cx.tcx.is_lang_item(pred.def_id(), hir::LangItem::MetaSized))
+                .filter(|pred| !cx.tcx.is_default_trait(pred.def_id()));
             if direct_super_traits_iter.count() > 1 {
                 cx.emit_span_lint(
                     MULTIPLE_SUPERTRAIT_UPCASTABLE,
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index f5f081efc49..51019db7c00 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -45,7 +45,7 @@ pub(crate) struct UnmatchedDelim {
 }
 
 /// Which tokens should be stripped before lexing the tokens.
-pub(crate) enum StripTokens {
+pub enum StripTokens {
     /// Strip both shebang and frontmatter.
     ShebangAndFrontmatter,
     /// Strip the shebang but not frontmatter.
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index d8792d7af4c..88b67d792de 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -54,29 +54,18 @@ pub fn unwrap_or_emit_fatal<T>(expr: Result<T, Vec<Diag<'_>>>) -> T {
     }
 }
 
-/// Creates a new parser from a source string. On failure, the errors must be consumed via
-/// `unwrap_or_emit_fatal`, `emit`, `cancel`, etc., otherwise a panic will occur when they are
-/// dropped.
-pub fn new_parser_from_source_str(
-    psess: &ParseSess,
-    name: FileName,
-    source: String,
-) -> Result<Parser<'_>, Vec<Diag<'_>>> {
-    let source_file = psess.source_map().new_source_file(name, source);
-    new_parser_from_source_file(psess, source_file, StripTokens::ShebangAndFrontmatter)
-}
-
-/// Creates a new parser from a simple (no shebang, no frontmatter) source string.
+/// Creates a new parser from a source string.
 ///
 /// On failure, the errors must be consumed via `unwrap_or_emit_fatal`, `emit`, `cancel`,
 /// etc., otherwise a panic will occur when they are dropped.
-pub fn new_parser_from_simple_source_str(
+pub fn new_parser_from_source_str(
     psess: &ParseSess,
     name: FileName,
     source: String,
+    strip_tokens: StripTokens,
 ) -> Result<Parser<'_>, Vec<Diag<'_>>> {
     let source_file = psess.source_map().new_source_file(name, source);
-    new_parser_from_source_file(psess, source_file, StripTokens::Nothing)
+    new_parser_from_source_file(psess, source_file, strip_tokens)
 }
 
 /// Creates a new parser from a filename. On failure, the errors must be consumed via
@@ -87,6 +76,7 @@ pub fn new_parser_from_simple_source_str(
 pub fn new_parser_from_file<'a>(
     psess: &'a ParseSess,
     path: &Path,
+    strip_tokens: StripTokens,
     sp: Option<Span>,
 ) -> Result<Parser<'a>, Vec<Diag<'a>>> {
     let sm = psess.source_map();
@@ -110,7 +100,7 @@ pub fn new_parser_from_file<'a>(
         }
         err.emit();
     });
-    new_parser_from_source_file(psess, source_file, StripTokens::ShebangAndFrontmatter)
+    new_parser_from_source_file(psess, source_file, strip_tokens)
 }
 
 pub fn utf8_error<E: EmissionGuarantee>(
@@ -172,6 +162,9 @@ fn new_parser_from_source_file(
     Ok(parser)
 }
 
+/// Given a source string, produces a sequence of token trees.
+///
+/// NOTE: This only strips shebangs, not frontmatter!
 pub fn source_str_to_stream(
     psess: &ParseSess,
     name: FileName,
@@ -179,13 +172,16 @@ pub fn source_str_to_stream(
     override_span: Option<Span>,
 ) -> Result<TokenStream, Vec<Diag<'_>>> {
     let source_file = psess.source_map().new_source_file(name, source);
-    // used mainly for `proc_macro` and the likes, not for our parsing purposes, so don't parse
-    // frontmatters as frontmatters, but for compatibility reason still strip the shebang
+    // FIXME(frontmatter): Consider stripping frontmatter in a future edition. We can't strip them
+    // in the current edition since that would be breaking.
+    // See also <https://github.com/rust-lang/rust/issues/145520>.
+    // Alternatively, stop stripping shebangs here, too, if T-lang and crater approve.
     source_file_to_stream(psess, source_file, override_span, StripTokens::Shebang)
 }
 
-/// Given a source file, produces a sequence of token trees. Returns any buffered errors from
-/// parsing the token stream.
+/// Given a source file, produces a sequence of token trees.
+///
+/// Returns any buffered errors from parsing the token stream.
 fn source_file_to_stream<'psess>(
     psess: &'psess ParseSess,
     source_file: Arc<SourceFile>,
diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs
index a6e7266e71b..e645fb47b9e 100644
--- a/compiler/rustc_parse/src/parser/tests.rs
+++ b/compiler/rustc_parse/src/parser/tests.rs
@@ -22,6 +22,7 @@ use rustc_span::{
 };
 use termcolor::WriteColor;
 
+use crate::lexer::StripTokens;
 use crate::parser::{ForceCollect, Parser};
 use crate::{new_parser_from_source_str, source_str_to_stream, unwrap_or_emit_fatal};
 
@@ -35,6 +36,7 @@ fn string_to_parser(psess: &ParseSess, source_str: String) -> Parser<'_> {
         psess,
         PathBuf::from("bogofile").into(),
         source_str,
+        StripTokens::Nothing,
     ))
 }
 
@@ -2240,7 +2242,7 @@ fn parse_item_from_source_str(
     source: String,
     psess: &ParseSess,
 ) -> PResult<'_, Option<Box<ast::Item>>> {
-    unwrap_or_emit_fatal(new_parser_from_source_str(psess, name, source))
+    unwrap_or_emit_fatal(new_parser_from_source_str(psess, name, source, StripTokens::Nothing))
         .parse_item(ForceCollect::No)
 }
 
@@ -2520,7 +2522,8 @@ fn ttdelim_span() {
         source: String,
         psess: &ParseSess,
     ) -> PResult<'_, Box<ast::Expr>> {
-        unwrap_or_emit_fatal(new_parser_from_source_str(psess, name, source)).parse_expr()
+        unwrap_or_emit_fatal(new_parser_from_source_str(psess, name, source, StripTokens::Nothing))
+            .parse_expr()
     }
 
     create_default_session_globals_then(|| {
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index e21ff83c400..aedeb0e14ed 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -21,18 +21,17 @@ mod tests;
 
 // The proc macro code for this is in `compiler/rustc_macros/src/symbols.rs`.
 symbols! {
-    // This list includes things that are definitely keywords (e.g. `if`),
-    // a few things that are definitely not keywords (e.g. the empty symbol,
-    // `{{root}}`) and things where there is disagreement between people and/or
-    // documents (such as the Rust Reference) about whether it is a keyword
-    // (e.g. `_`).
+    // This list includes things that are definitely keywords (e.g. `if`), a
+    // few things that are definitely not keywords (e.g. `{{root}}`) and things
+    // where there is disagreement between people and/or documents (such as the
+    // Rust Reference) about whether it is a keyword (e.g. `_`).
     //
     // If you modify this list, adjust any relevant `Symbol::{is,can_be}_*`
     // predicates and `used_keywords`. Also consider adding new keywords to the
     // `ui/parser/raw/raw-idents.rs` test.
     Keywords {
-        // Special reserved identifiers used internally for elided lifetimes,
-        // unnamed method parameters, crate root module, error recovery etc.
+        // Special reserved identifiers used internally for unnamed method
+        // parameters, crate root module, etc.
         // Matching predicates: `is_special`/`is_reserved`
         //
         // tidy-alphabetical-start
diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs
index 57a980d6acd..21e82d43a80 100644
--- a/library/std/src/io/error.rs
+++ b/library/std/src/io/error.rs
@@ -95,6 +95,9 @@ impl Error {
 
     pub(crate) const ZERO_TIMEOUT: Self =
         const_error!(ErrorKind::InvalidInput, "cannot set a 0 duration timeout");
+
+    pub(crate) const NO_ADDRESSES: Self =
+        const_error!(ErrorKind::InvalidInput, "could not resolve to any addresses");
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/std/src/net/mod.rs b/library/std/src/net/mod.rs
index ddd3b68dd2d..40f1a93e39d 100644
--- a/library/std/src/net/mod.rs
+++ b/library/std/src/net/mod.rs
@@ -34,7 +34,6 @@ pub use self::tcp::IntoIncoming;
 pub use self::tcp::{Incoming, TcpListener, TcpStream};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::udp::UdpSocket;
-use crate::io::{self, ErrorKind};
 
 mod ip_addr;
 mod socket_addr;
@@ -67,23 +66,3 @@ pub enum Shutdown {
     #[stable(feature = "rust1", since = "1.0.0")]
     Both,
 }
-
-fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T>
-where
-    F: FnMut(io::Result<&SocketAddr>) -> io::Result<T>,
-{
-    let addrs = match addr.to_socket_addrs() {
-        Ok(addrs) => addrs,
-        Err(e) => return f(Err(e)),
-    };
-    let mut last_err = None;
-    for addr in addrs {
-        match f(Ok(&addr)) {
-            Ok(l) => return Ok(l),
-            Err(e) => last_err = Some(e),
-        }
-    }
-    Err(last_err.unwrap_or_else(|| {
-        io::const_error!(ErrorKind::InvalidInput, "could not resolve to any addresses")
-    }))
-}
diff --git a/library/std/src/net/tcp.rs b/library/std/src/net/tcp.rs
index 10685b49319..ae50f531a71 100644
--- a/library/std/src/net/tcp.rs
+++ b/library/std/src/net/tcp.rs
@@ -167,7 +167,7 @@ impl TcpStream {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<TcpStream> {
-        super::each_addr(addr, net_imp::TcpStream::connect).map(TcpStream)
+        net_imp::TcpStream::connect(addr).map(TcpStream)
     }
 
     /// Opens a TCP connection to a remote host with a timeout.
@@ -782,7 +782,7 @@ impl TcpListener {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> {
-        super::each_addr(addr, net_imp::TcpListener::bind).map(TcpListener)
+        net_imp::TcpListener::bind(addr).map(TcpListener)
     }
 
     /// Returns the local socket address of this listener.
diff --git a/library/std/src/net/tcp/tests.rs b/library/std/src/net/tcp/tests.rs
index 03003037b29..7c7ef7b2f70 100644
--- a/library/std/src/net/tcp/tests.rs
+++ b/library/std/src/net/tcp/tests.rs
@@ -1,5 +1,5 @@
 use crate::io::prelude::*;
-use crate::io::{BorrowedBuf, IoSlice, IoSliceMut};
+use crate::io::{BorrowedBuf, ErrorKind, IoSlice, IoSliceMut};
 use crate::mem::MaybeUninit;
 use crate::net::test::{next_test_ip4, next_test_ip6};
 use crate::net::*;
diff --git a/library/std/src/net/udp.rs b/library/std/src/net/udp.rs
index a97b3299774..72e292e3d15 100644
--- a/library/std/src/net/udp.rs
+++ b/library/std/src/net/udp.rs
@@ -120,7 +120,7 @@ impl UdpSocket {
     /// [`Ipv4Addr::UNSPECIFIED`] or [`Ipv6Addr::UNSPECIFIED`].
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<UdpSocket> {
-        super::each_addr(addr, net_imp::UdpSocket::bind).map(UdpSocket)
+        net_imp::UdpSocket::bind(addr).map(UdpSocket)
     }
 
     /// Receives a single datagram message on the socket. On success, returns the number
@@ -677,7 +677,7 @@ impl UdpSocket {
     /// on the platform.
     #[stable(feature = "net2_mutators", since = "1.9.0")]
     pub fn connect<A: ToSocketAddrs>(&self, addr: A) -> io::Result<()> {
-        super::each_addr(addr, |addr| self.0.connect(addr))
+        self.0.connect(addr)
     }
 
     /// Sends data on the socket to the remote address to which it is connected.
diff --git a/library/std/src/net/udp/tests.rs b/library/std/src/net/udp/tests.rs
index 91da3135f97..0638b36c54f 100644
--- a/library/std/src/net/udp/tests.rs
+++ b/library/std/src/net/udp/tests.rs
@@ -1,3 +1,4 @@
+use crate::io::ErrorKind;
 use crate::net::test::{compare_ignore_zoneid, next_test_ip4, next_test_ip6};
 use crate::net::*;
 use crate::sync::mpsc::channel;
diff --git a/library/std/src/sync/barrier.rs b/library/std/src/sync/barrier.rs
index 712ce03f90b..8988126bd90 100644
--- a/library/std/src/sync/barrier.rs
+++ b/library/std/src/sync/barrier.rs
@@ -1,4 +1,5 @@
 use crate::fmt;
+use crate::panic::RefUnwindSafe;
 use crate::sync::nonpoison::{Condvar, Mutex};
 
 /// A barrier enables multiple threads to synchronize the beginning
@@ -31,6 +32,9 @@ pub struct Barrier {
     num_threads: usize,
 }
 
+#[stable(feature = "unwind_safe_lock_refs", since = "1.12.0")]
+impl RefUnwindSafe for Barrier {}
+
 // The inner state of a double barrier
 struct BarrierState {
     count: usize,
diff --git a/library/std/src/sys/net/connection/mod.rs b/library/std/src/sys/net/connection/mod.rs
new file mode 100644
index 00000000000..7f9636a8ccf
--- /dev/null
+++ b/library/std/src/sys/net/connection/mod.rs
@@ -0,0 +1,57 @@
+cfg_select! {
+    any(
+        all(target_family = "unix", not(target_os = "l4re")),
+        target_os = "windows",
+        target_os = "hermit",
+        all(target_os = "wasi", target_env = "p2"),
+        target_os = "solid_asp3",
+    ) => {
+        mod socket;
+        pub use socket::*;
+    }
+    all(target_vendor = "fortanix", target_env = "sgx") => {
+        mod sgx;
+        pub use sgx::*;
+    }
+    all(target_os = "wasi", target_env = "p1") => {
+        mod wasip1;
+        pub use wasip1::*;
+    }
+    target_os = "xous" => {
+        mod xous;
+        pub use xous::*;
+    }
+    target_os = "uefi" => {
+        mod uefi;
+        pub use uefi::*;
+    }
+    _ => {
+        mod unsupported;
+        pub use unsupported::*;
+    }
+}
+
+#[cfg_attr(
+    // Make sure that this is used on some platforms at least.
+    not(any(target_os = "linux", target_os = "windows")),
+    allow(dead_code)
+)]
+fn each_addr<A: crate::net::ToSocketAddrs, F, T>(addr: A, mut f: F) -> crate::io::Result<T>
+where
+    F: FnMut(&crate::net::SocketAddr) -> crate::io::Result<T>,
+{
+    use crate::io::Error;
+
+    let mut last_err = None;
+    for addr in addr.to_socket_addrs()? {
+        match f(&addr) {
+            Ok(l) => return Ok(l),
+            Err(e) => last_err = Some(e),
+        }
+    }
+
+    match last_err {
+        Some(err) => Err(err),
+        None => Err(Error::NO_ADDRESSES),
+    }
+}
diff --git a/library/std/src/sys/net/connection/sgx.rs b/library/std/src/sys/net/connection/sgx.rs
index 2389fd1bcb6..9b54571997d 100644
--- a/library/std/src/sys/net/connection/sgx.rs
+++ b/library/std/src/sys/net/connection/sgx.rs
@@ -1,3 +1,5 @@
+use crate::error;
+use crate::fmt::{self, Write};
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
 use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, ToSocketAddrs};
 use crate::sync::Arc;
@@ -5,7 +7,6 @@ use crate::sys::abi::usercalls;
 use crate::sys::fd::FileDesc;
 use crate::sys::{AsInner, FromInner, IntoInner, TryIntoInner, sgx_ineffective, unsupported};
 use crate::time::Duration;
-use crate::{error, fmt};
 
 const DEFAULT_FAKE_TTL: u32 = 64;
 
@@ -63,18 +64,52 @@ impl fmt::Debug for TcpStream {
     }
 }
 
-fn io_err_to_addr(result: io::Result<&SocketAddr>) -> io::Result<String> {
-    match result {
-        Ok(saddr) => Ok(saddr.to_string()),
-        // need to downcast twice because io::Error::into_inner doesn't return the original
-        // value if the conversion fails
-        Err(e) => {
-            if e.get_ref().and_then(|e| e.downcast_ref::<NonIpSockAddr>()).is_some() {
-                Ok(e.into_inner().unwrap().downcast::<NonIpSockAddr>().unwrap().host)
-            } else {
-                Err(e)
+/// Converts each address in `addr` into a hostname.
+///
+/// SGX doesn't support DNS resolution but rather accepts hostnames in
+/// the same place as socket addresses. So, to make e.g.
+/// ```rust
+/// TcpStream::connect("example.com:80")`
+/// ```
+/// work, the DNS lookup returns a special error (`NonIpSockAddr`) instead,
+/// which contains the hostname being looked up. When `.to_socket_addrs()`
+/// fails, we inspect the error and try recover the hostname from it. If that
+/// succeeds, we thus continue with the hostname.
+///
+/// This is a terrible hack and leads to buggy code. For instance, when users
+/// use the result of `.to_socket_addrs()` in their own `ToSocketAddrs`
+/// implementation to select from a list of possible URLs, the only URL used
+/// will be that of the last item tried.
+// FIXME: This is a terrible, terrible hack. Fixing this requires Fortanix to
+// add a method for resolving addresses.
+fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T>
+where
+    F: FnMut(&str) -> io::Result<T>,
+{
+    match addr.to_socket_addrs() {
+        Ok(addrs) => {
+            let mut last_err = None;
+            let mut encoded = String::new();
+            for addr in addrs {
+                // Format the IP address as a string, reusing the buffer.
+                encoded.clear();
+                write!(encoded, "{}", &addr).unwrap();
+
+                match f(&encoded) {
+                    Ok(val) => return Ok(val),
+                    Err(err) => last_err = Some(err),
+                }
+            }
+
+            match last_err {
+                Some(err) => Err(err),
+                None => Err(io::Error::NO_ADDRESSES),
             }
         }
+        Err(err) => match err.get_ref().and_then(|e| e.downcast_ref::<NonIpSockAddr>()) {
+            Some(NonIpSockAddr { host }) => f(host),
+            None => Err(err),
+        },
     }
 }
 
@@ -86,17 +121,18 @@ fn addr_to_sockaddr(addr: Option<&str>) -> io::Result<SocketAddr> {
 }
 
 impl TcpStream {
-    pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
-        let addr = io_err_to_addr(addr)?;
-        let (fd, local_addr, peer_addr) = usercalls::connect_stream(&addr)?;
-        Ok(TcpStream { inner: Socket::new(fd, local_addr), peer_addr: Some(peer_addr) })
+    pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<TcpStream> {
+        each_addr(addr, |addr| {
+            let (fd, local_addr, peer_addr) = usercalls::connect_stream(addr)?;
+            Ok(TcpStream { inner: Socket::new(fd, local_addr), peer_addr: Some(peer_addr) })
+        })
     }
 
     pub fn connect_timeout(addr: &SocketAddr, dur: Duration) -> io::Result<TcpStream> {
         if dur == Duration::default() {
             return Err(io::Error::ZERO_TIMEOUT);
         }
-        Self::connect(Ok(addr)) // FIXME: ignoring timeout
+        Self::connect(addr) // FIXME: ignoring timeout
     }
 
     pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
@@ -247,10 +283,11 @@ impl fmt::Debug for TcpListener {
 }
 
 impl TcpListener {
-    pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
-        let addr = io_err_to_addr(addr)?;
-        let (fd, local_addr) = usercalls::bind_stream(&addr)?;
-        Ok(TcpListener { inner: Socket::new(fd, local_addr) })
+    pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> {
+        each_addr(addr, |addr| {
+            let (fd, local_addr) = usercalls::bind_stream(addr)?;
+            Ok(TcpListener { inner: Socket::new(fd, local_addr) })
+        })
     }
 
     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
@@ -316,7 +353,7 @@ impl FromInner<Socket> for TcpListener {
 pub struct UdpSocket(!);
 
 impl UdpSocket {
-    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
+    pub fn bind<A: ToSocketAddrs>(_: A) -> io::Result<UdpSocket> {
         unsupported()
     }
 
@@ -436,7 +473,7 @@ impl UdpSocket {
         self.0
     }
 
-    pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
+    pub fn connect<A: ToSocketAddrs>(&self, _: A) -> io::Result<()> {
         self.0
     }
 }
diff --git a/library/std/src/sys/net/connection/socket.rs b/library/std/src/sys/net/connection/socket/mod.rs
index aa83ed65d4c..564f2e3a01f 100644
--- a/library/std/src/sys/net/connection/socket.rs
+++ b/library/std/src/sys/net/connection/socket/mod.rs
@@ -3,8 +3,11 @@ mod tests;
 
 use crate::ffi::{c_int, c_void};
 use crate::io::{self, BorrowedCursor, ErrorKind, IoSlice, IoSliceMut};
-use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, SocketAddrV4, SocketAddrV6};
+use crate::net::{
+    Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs,
+};
 use crate::sys::common::small_c_string::run_with_cstr;
+use crate::sys::net::connection::each_addr;
 use crate::sys_common::{AsInner, FromInner};
 use crate::time::Duration;
 use crate::{cmp, fmt, mem, ptr};
@@ -342,14 +345,15 @@ pub struct TcpStream {
 }
 
 impl TcpStream {
-    pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
-        let addr = addr?;
-
+    pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<TcpStream> {
         init();
+        return each_addr(addr, inner);
 
-        let sock = Socket::new(addr, c::SOCK_STREAM)?;
-        sock.connect(addr)?;
-        Ok(TcpStream { inner: sock })
+        fn inner(addr: &SocketAddr) -> io::Result<TcpStream> {
+            let sock = Socket::new(addr, c::SOCK_STREAM)?;
+            sock.connect(addr)?;
+            Ok(TcpStream { inner: sock })
+        }
     }
 
     pub fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result<TcpStream> {
@@ -512,48 +516,45 @@ pub struct TcpListener {
 }
 
 impl TcpListener {
-    pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
-        let addr = addr?;
-
+    pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> {
         init();
-
-        let sock = Socket::new(addr, c::SOCK_STREAM)?;
-
-        // On platforms with Berkeley-derived sockets, this allows to quickly
-        // rebind a socket, without needing to wait for the OS to clean up the
-        // previous one.
-        //
-        // On Windows, this allows rebinding sockets which are actively in use,
-        // which allows “socket hijacking”, so we explicitly don't set it here.
-        // https://docs.microsoft.com/en-us/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse
-        #[cfg(not(windows))]
-        setsockopt(&sock, c::SOL_SOCKET, c::SO_REUSEADDR, 1 as c_int)?;
-
-        // Bind our new socket
-        let (addr, len) = socket_addr_to_c(addr);
-        cvt(unsafe { c::bind(sock.as_raw(), addr.as_ptr(), len as _) })?;
-
-        cfg_select! {
-            target_os = "horizon" => {
+        return each_addr(addr, inner);
+
+        fn inner(addr: &SocketAddr) -> io::Result<TcpListener> {
+            let sock = Socket::new(addr, c::SOCK_STREAM)?;
+
+            // On platforms with Berkeley-derived sockets, this allows to quickly
+            // rebind a socket, without needing to wait for the OS to clean up the
+            // previous one.
+            //
+            // On Windows, this allows rebinding sockets which are actively in use,
+            // which allows “socket hijacking”, so we explicitly don't set it here.
+            // https://docs.microsoft.com/en-us/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse
+            #[cfg(not(windows))]
+            setsockopt(&sock, c::SOL_SOCKET, c::SO_REUSEADDR, 1 as c_int)?;
+
+            // Bind our new socket
+            let (addr, len) = socket_addr_to_c(addr);
+            cvt(unsafe { c::bind(sock.as_raw(), addr.as_ptr(), len as _) })?;
+
+            let backlog = if cfg!(target_os = "horizon") {
                 // The 3DS doesn't support a big connection backlog. Sometimes
                 // it allows up to about 37, but other times it doesn't even
                 // accept 32. There may be a global limitation causing this.
-                let backlog = 20;
-            }
-            target_os = "haiku" => {
+                20
+            } else if cfg!(target_os = "haiku") {
                 // Haiku does not support a queue length > 32
                 // https://github.com/haiku/haiku/blob/979a0bc487864675517fb2fab28f87dc8bf43041/headers/posix/sys/socket.h#L81
-                let backlog = 32;
-            }
-            _ => {
+                32
+            } else {
                 // The default for all other platforms
-                let backlog = 128;
-            }
-        }
+                128
+            };
 
-        // Start listening
-        cvt(unsafe { c::listen(sock.as_raw(), backlog) })?;
-        Ok(TcpListener { inner: sock })
+            // Start listening
+            cvt(unsafe { c::listen(sock.as_raw(), backlog) })?;
+            Ok(TcpListener { inner: sock })
+        }
     }
 
     #[inline]
@@ -639,15 +640,16 @@ pub struct UdpSocket {
 }
 
 impl UdpSocket {
-    pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
-        let addr = addr?;
-
+    pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<UdpSocket> {
         init();
+        return each_addr(addr, inner);
 
-        let sock = Socket::new(addr, c::SOCK_DGRAM)?;
-        let (addr, len) = socket_addr_to_c(addr);
-        cvt(unsafe { c::bind(sock.as_raw(), addr.as_ptr(), len as _) })?;
-        Ok(UdpSocket { inner: sock })
+        fn inner(addr: &SocketAddr) -> io::Result<UdpSocket> {
+            let sock = Socket::new(addr, c::SOCK_DGRAM)?;
+            let (addr, len) = socket_addr_to_c(addr);
+            cvt(unsafe { c::bind(sock.as_raw(), addr.as_ptr(), len as _) })?;
+            Ok(UdpSocket { inner: sock })
+        }
     }
 
     #[inline]
@@ -822,9 +824,13 @@ impl UdpSocket {
         Ok(ret as usize)
     }
 
-    pub fn connect(&self, addr: io::Result<&SocketAddr>) -> io::Result<()> {
-        let (addr, len) = socket_addr_to_c(addr?);
-        cvt_r(|| unsafe { c::connect(self.inner.as_raw(), addr.as_ptr(), len) }).map(drop)
+    pub fn connect<A: ToSocketAddrs>(&self, addr: A) -> io::Result<()> {
+        return each_addr(addr, |addr| inner(self, addr));
+
+        fn inner(this: &UdpSocket, addr: &SocketAddr) -> io::Result<()> {
+            let (addr, len) = socket_addr_to_c(addr);
+            cvt_r(|| unsafe { c::connect(this.inner.as_raw(), addr.as_ptr(), len) }).map(drop)
+        }
     }
 }
 
diff --git a/library/std/src/sys/net/connection/uefi/mod.rs b/library/std/src/sys/net/connection/uefi/mod.rs
index 16e3487a174..00368042873 100644
--- a/library/std/src/sys/net/connection/uefi/mod.rs
+++ b/library/std/src/sys/net/connection/uefi/mod.rs
@@ -1,6 +1,7 @@
+use super::each_addr;
 use crate::fmt;
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
-use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
+use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, ToSocketAddrs};
 use crate::sync::{Arc, Mutex};
 use crate::sys::unsupported;
 use crate::time::Duration;
@@ -15,13 +16,17 @@ pub struct TcpStream {
 }
 
 impl TcpStream {
-    pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
-        let inner = tcp::Tcp::connect(addr?, None)?;
-        Ok(Self {
-            inner,
-            read_timeout: Arc::new(Mutex::new(None)),
-            write_timeout: Arc::new(Mutex::new(None)),
-        })
+    pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<TcpStream> {
+        return each_addr(addr, inner);
+
+        fn inner(addr: &SocketAddr) -> io::Result<TcpStream> {
+            let inner = tcp::Tcp::connect(addr, None)?;
+            Ok(TcpStream {
+                inner,
+                read_timeout: Arc::new(Mutex::new(None)),
+                write_timeout: Arc::new(Mutex::new(None)),
+            })
+        }
     }
 
     pub fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result<TcpStream> {
@@ -145,7 +150,7 @@ pub struct TcpListener {
 }
 
 impl TcpListener {
-    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
+    pub fn bind<A: ToSocketAddrs>(_: A) -> io::Result<TcpListener> {
         unsupported()
     }
 
@@ -195,7 +200,7 @@ impl fmt::Debug for TcpListener {
 pub struct UdpSocket(!);
 
 impl UdpSocket {
-    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
+    pub fn bind<A: ToSocketAddrs>(_: A) -> io::Result<UdpSocket> {
         unsupported()
     }
 
@@ -315,7 +320,7 @@ impl UdpSocket {
         self.0
     }
 
-    pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
+    pub fn connect<A: ToSocketAddrs>(&self, _: A) -> io::Result<()> {
         self.0
     }
 }
diff --git a/library/std/src/sys/net/connection/unsupported.rs b/library/std/src/sys/net/connection/unsupported.rs
index da217439626..fbc86343272 100644
--- a/library/std/src/sys/net/connection/unsupported.rs
+++ b/library/std/src/sys/net/connection/unsupported.rs
@@ -1,13 +1,13 @@
 use crate::fmt;
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
-use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
+use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, ToSocketAddrs};
 use crate::sys::unsupported;
 use crate::time::Duration;
 
 pub struct TcpStream(!);
 
 impl TcpStream {
-    pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
+    pub fn connect<A: ToSocketAddrs>(_: A) -> io::Result<TcpStream> {
         unsupported()
     }
 
@@ -121,7 +121,7 @@ impl fmt::Debug for TcpStream {
 pub struct TcpListener(!);
 
 impl TcpListener {
-    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
+    pub fn bind<A: ToSocketAddrs>(_: A) -> io::Result<TcpListener> {
         unsupported()
     }
 
@@ -171,7 +171,7 @@ impl fmt::Debug for TcpListener {
 pub struct UdpSocket(!);
 
 impl UdpSocket {
-    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
+    pub fn bind<A: ToSocketAddrs>(_: A) -> io::Result<UdpSocket> {
         unsupported()
     }
 
@@ -291,7 +291,7 @@ impl UdpSocket {
         self.0
     }
 
-    pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
+    pub fn connect<A: ToSocketAddrs>(&self, _: A) -> io::Result<()> {
         self.0
     }
 }
diff --git a/library/std/src/sys/net/connection/wasip1.rs b/library/std/src/sys/net/connection/wasip1.rs
index 951dc65e5b4..cdfa25c8a44 100644
--- a/library/std/src/sys/net/connection/wasip1.rs
+++ b/library/std/src/sys/net/connection/wasip1.rs
@@ -2,7 +2,7 @@
 
 use crate::fmt;
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
-use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
+use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, ToSocketAddrs};
 use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
 use crate::sys::fd::WasiFd;
 use crate::sys::{err2io, unsupported};
@@ -60,7 +60,7 @@ impl FromRawFd for Socket {
 }
 
 impl TcpStream {
-    pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
+    pub fn connect<A: ToSocketAddrs>(_: A) -> io::Result<TcpStream> {
         unsupported()
     }
 
@@ -212,7 +212,7 @@ pub struct TcpListener {
 }
 
 impl TcpListener {
-    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
+    pub fn bind<A: ToSocketAddrs>(_: A) -> io::Result<TcpListener> {
         unsupported()
     }
 
@@ -316,7 +316,7 @@ pub struct UdpSocket {
 }
 
 impl UdpSocket {
-    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
+    pub fn bind<A: ToSocketAddrs>(_: A) -> io::Result<UdpSocket> {
         unsupported()
     }
 
@@ -436,7 +436,7 @@ impl UdpSocket {
         unsupported()
     }
 
-    pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
+    pub fn connect<A: ToSocketAddrs>(&self, _: A) -> io::Result<()> {
         unsupported()
     }
 
diff --git a/library/std/src/sys/net/connection/xous/tcplistener.rs b/library/std/src/sys/net/connection/xous/tcplistener.rs
index bdf1fcd9302..8818ef2ca9a 100644
--- a/library/std/src/sys/net/connection/xous/tcplistener.rs
+++ b/library/std/src/sys/net/connection/xous/tcplistener.rs
@@ -2,9 +2,10 @@ use core::convert::TryInto;
 use core::sync::atomic::{Atomic, AtomicBool, AtomicU16, AtomicUsize, Ordering};
 
 use super::*;
-use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
+use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs};
 use crate::os::xous::services;
 use crate::sync::Arc;
+use crate::sys::net::connection::each_addr;
 use crate::{fmt, io};
 
 macro_rules! unimpl {
@@ -25,16 +26,19 @@ pub struct TcpListener {
 }
 
 impl TcpListener {
-    pub fn bind(socketaddr: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
-        let mut addr = *socketaddr?;
-
-        let fd = TcpListener::bind_inner(&mut addr)?;
-        return Ok(TcpListener {
-            fd: Arc::new(AtomicU16::new(fd)),
-            local: addr,
-            handle_count: Arc::new(AtomicUsize::new(1)),
-            nonblocking: Arc::new(AtomicBool::new(false)),
-        });
+    pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> {
+        return each_addr(addr, inner);
+
+        fn inner(addr: &SocketAddr) -> io::Result<TcpListener> {
+            let mut addr = *addr;
+            let fd = TcpListener::bind_inner(&mut addr)?;
+            Ok(TcpListener {
+                fd: Arc::new(AtomicU16::new(fd)),
+                local: addr,
+                handle_count: Arc::new(AtomicUsize::new(1)),
+                nonblocking: Arc::new(AtomicBool::new(false)),
+            })
+        }
     }
 
     /// This returns the raw fd of a Listener, so that it can also be used by the
diff --git a/library/std/src/sys/net/connection/xous/tcpstream.rs b/library/std/src/sys/net/connection/xous/tcpstream.rs
index 54524767452..4df75453d1f 100644
--- a/library/std/src/sys/net/connection/xous/tcpstream.rs
+++ b/library/std/src/sys/net/connection/xous/tcpstream.rs
@@ -3,9 +3,12 @@ use core::sync::atomic::{Atomic, AtomicBool, AtomicU32, AtomicUsize, Ordering};
 use super::*;
 use crate::fmt;
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
-use crate::net::{IpAddr, Ipv4Addr, Shutdown, SocketAddr, SocketAddrV4, SocketAddrV6};
+use crate::net::{
+    IpAddr, Ipv4Addr, Shutdown, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs,
+};
 use crate::os::xous::services;
 use crate::sync::Arc;
+use crate::sys::net::connection::each_addr;
 use crate::time::Duration;
 
 macro_rules! unimpl {
@@ -79,8 +82,8 @@ impl TcpStream {
         }
     }
 
-    pub fn connect(socketaddr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
-        Self::connect_timeout(socketaddr?, Duration::ZERO)
+    pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<TcpStream> {
+        each_addr(addr, |addr| Self::connect_timeout(addr, Duration::ZERO))
     }
 
     pub fn connect_timeout(addr: &SocketAddr, duration: Duration) -> io::Result<TcpStream> {
diff --git a/library/std/src/sys/net/connection/xous/udp.rs b/library/std/src/sys/net/connection/xous/udp.rs
index 2127d3267ed..ce54ea3b79e 100644
--- a/library/std/src/sys/net/connection/xous/udp.rs
+++ b/library/std/src/sys/net/connection/xous/udp.rs
@@ -3,9 +3,10 @@ use core::sync::atomic::{Atomic, AtomicUsize, Ordering};
 
 use super::*;
 use crate::cell::Cell;
-use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
+use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs};
 use crate::os::xous::services;
 use crate::sync::Arc;
+use crate::sys::net::connection::each_addr;
 use crate::time::Duration;
 use crate::{fmt, io};
 
@@ -32,40 +33,45 @@ pub struct UdpSocket {
 }
 
 impl UdpSocket {
-    pub fn bind(socketaddr: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
-        let addr = socketaddr?;
-        // Construct the request
-        let mut connect_request = ConnectRequest { raw: [0u8; 4096] };
-
-        // Serialize the StdUdpBind structure. This is done "manually" because we don't want to
-        // make an auto-serdes (like bincode or rkyv) crate a dependency of Xous.
-        let port_bytes = addr.port().to_le_bytes();
-        connect_request.raw[0] = port_bytes[0];
-        connect_request.raw[1] = port_bytes[1];
-        match addr.ip() {
-            IpAddr::V4(addr) => {
-                connect_request.raw[2] = 4;
-                for (dest, src) in connect_request.raw[3..].iter_mut().zip(addr.octets()) {
-                    *dest = src;
+    pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<UdpSocket> {
+        return each_addr(addr, inner);
+
+        fn inner(addr: &SocketAddr) -> io::Result<UdpSocket> {
+            // Construct the request
+            let mut connect_request = ConnectRequest { raw: [0u8; 4096] };
+
+            // Serialize the StdUdpBind structure. This is done "manually" because we don't want to
+            // make an auto-serdes (like bincode or rkyv) crate a dependency of Xous.
+            let port_bytes = addr.port().to_le_bytes();
+            connect_request.raw[0] = port_bytes[0];
+            connect_request.raw[1] = port_bytes[1];
+            match addr.ip() {
+                IpAddr::V4(addr) => {
+                    connect_request.raw[2] = 4;
+                    for (dest, src) in connect_request.raw[3..].iter_mut().zip(addr.octets()) {
+                        *dest = src;
+                    }
                 }
-            }
-            IpAddr::V6(addr) => {
-                connect_request.raw[2] = 6;
-                for (dest, src) in connect_request.raw[3..].iter_mut().zip(addr.octets()) {
-                    *dest = src;
+                IpAddr::V6(addr) => {
+                    connect_request.raw[2] = 6;
+                    for (dest, src) in connect_request.raw[3..].iter_mut().zip(addr.octets()) {
+                        *dest = src;
+                    }
                 }
             }
-        }
 
-        let response = crate::os::xous::ffi::lend_mut(
-            services::net_server(),
-            services::NetLendMut::StdUdpBind.into(),
-            &mut connect_request.raw,
-            0,
-            4096,
-        );
+            let response = crate::os::xous::ffi::lend_mut(
+                services::net_server(),
+                services::NetLendMut::StdUdpBind.into(),
+                &mut connect_request.raw,
+                0,
+                4096,
+            );
+
+            let Ok((_, valid)) = response else {
+                return Err(io::const_error!(io::ErrorKind::InvalidInput, "invalid response"));
+            };
 
-        if let Ok((_, valid)) = response {
             // The first four bytes should be zero upon success, and will be nonzero
             // for an error.
             let response = connect_request.raw;
@@ -87,8 +93,9 @@ impl UdpSocket {
                     ));
                 }
             }
+
             let fd = response[1] as u16;
-            return Ok(UdpSocket {
+            Ok(UdpSocket {
                 fd,
                 local: *addr,
                 remote: Cell::new(None),
@@ -96,9 +103,8 @@ impl UdpSocket {
                 write_timeout: Cell::new(0),
                 handle_count: Arc::new(AtomicUsize::new(1)),
                 nonblocking: Cell::new(false),
-            });
+            })
         }
-        Err(io::const_error!(io::ErrorKind::InvalidInput, "invalid response"))
     }
 
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
@@ -198,10 +204,11 @@ impl UdpSocket {
         self.peek_from(buf).map(|(len, _addr)| len)
     }
 
-    pub fn connect(&self, maybe_addr: io::Result<&SocketAddr>) -> io::Result<()> {
-        let addr = maybe_addr?;
-        self.remote.set(Some(*addr));
-        Ok(())
+    pub fn connect<A: ToSocketAddrs>(&self, addr: A) -> io::Result<()> {
+        each_addr(addr, |addr| {
+            self.remote.set(Some(*addr));
+            Ok(())
+        })
     }
 
     pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
diff --git a/library/std/src/sys/net/mod.rs b/library/std/src/sys/net/mod.rs
index 5df1fe138ab..dffc4ea7f81 100644
--- a/library/std/src/sys/net/mod.rs
+++ b/library/std/src/sys/net/mod.rs
@@ -1,46 +1,4 @@
-cfg_select! {
-    any(
-        all(target_family = "unix", not(target_os = "l4re")),
-        target_os = "windows",
-        target_os = "hermit",
-        all(target_os = "wasi", target_env = "p2"),
-        target_os = "solid_asp3",
-    ) => {
-        mod connection {
-            mod socket;
-            pub use socket::*;
-        }
-    }
-    all(target_vendor = "fortanix", target_env = "sgx") => {
-        mod connection {
-            mod sgx;
-            pub use sgx::*;
-        }
-    }
-    all(target_os = "wasi", target_env = "p1") => {
-        mod connection {
-            mod wasip1;
-            pub use wasip1::*;
-        }
-    }
-    target_os = "xous" => {
-        mod connection {
-            mod xous;
-            pub use xous::*;
-        }
-    }
-    target_os = "uefi" => {
-        mod connection {
-            mod uefi;
-            pub use uefi::*;
-        }
-    }
-    _ => {
-        mod connection {
-            mod unsupported;
-            pub use unsupported::*;
-        }
-    }
-}
-
+/// This module contains the implementations of `TcpStream`, `TcpListener` and
+/// `UdpSocket` as well as related functionality like DNS resolving.
+mod connection;
 pub use connection::*;
diff --git a/library/std/tests/sync/barrier.rs b/library/std/tests/sync/barrier.rs
index 8aefff9d507..a66bd629699 100644
--- a/library/std/tests/sync/barrier.rs
+++ b/library/std/tests/sync/barrier.rs
@@ -1,3 +1,4 @@
+use std::panic::RefUnwindSafe;
 use std::sync::mpsc::{TryRecvError, channel};
 use std::sync::{Arc, Barrier};
 use std::thread;
@@ -33,3 +34,11 @@ fn test_barrier() {
     }
     assert!(leader_found);
 }
+
+/// Asserts that `Barrier` is ref unwind safe.
+///
+/// See <https://github.com/rust-lang/rust/issues/146087>.
+const _: () = {
+    const fn check_ref_unwind_safe<T: RefUnwindSafe>() {}
+    check_ref_unwind_safe::<Barrier>();
+};
diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs
index d684e6f8650..b5a8d64ff4f 100644
--- a/src/librustdoc/clean/render_macro_matchers.rs
+++ b/src/librustdoc/clean/render_macro_matchers.rs
@@ -3,6 +3,7 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree};
 use rustc_ast_pretty::pprust::PrintState;
 use rustc_ast_pretty::pprust::state::State as Printer;
 use rustc_middle::ty::TyCtxt;
+use rustc_parse::lexer::StripTokens;
 use rustc_session::parse::ParseSess;
 use rustc_span::symbol::{Ident, Symbol, kw};
 use rustc_span::{FileName, Span};
@@ -64,14 +65,18 @@ fn snippet_equal_to_token(tcx: TyCtxt<'_>, matcher: &TokenTree) -> Option<String
     // Create a Parser.
     let psess = ParseSess::new(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec());
     let file_name = FileName::macro_expansion_source_code(&snippet);
-    let mut parser =
-        match rustc_parse::new_parser_from_source_str(&psess, file_name, snippet.clone()) {
-            Ok(parser) => parser,
-            Err(errs) => {
-                errs.into_iter().for_each(|err| err.cancel());
-                return None;
-            }
-        };
+    let mut parser = match rustc_parse::new_parser_from_source_str(
+        &psess,
+        file_name,
+        snippet.clone(),
+        StripTokens::Nothing,
+    ) {
+        Ok(parser) => parser,
+        Err(errs) => {
+            errs.into_iter().for_each(|err| err.cancel());
+            return None;
+        }
+    };
 
     // Reparse a single token tree.
     if parser.token == token::Eof {
diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs
index f229f77c978..5eaadc9eb45 100644
--- a/src/librustdoc/doctest/make.rs
+++ b/src/librustdoc/doctest/make.rs
@@ -10,6 +10,7 @@ use rustc_ast::tokenstream::TokenTree;
 use rustc_ast::{self as ast, AttrStyle, HasAttrs, StmtKind};
 use rustc_errors::emitter::stderr_destination;
 use rustc_errors::{ColorConfig, DiagCtxtHandle};
+use rustc_parse::lexer::StripTokens;
 use rustc_parse::new_parser_from_source_str;
 use rustc_session::parse::ParseSess;
 use rustc_span::edition::{DEFAULT_EDITION, Edition};
@@ -468,14 +469,16 @@ fn parse_source(
     let dcx = DiagCtxt::new(Box::new(emitter)).disable_warnings();
     let psess = ParseSess::with_dcx(dcx, sm);
 
-    let mut parser = match new_parser_from_source_str(&psess, filename, wrapped_source) {
-        Ok(p) => p,
-        Err(errs) => {
-            errs.into_iter().for_each(|err| err.cancel());
-            reset_error_count(&psess);
-            return Err(());
-        }
-    };
+    // Don't strip any tokens; it wouldn't matter anyway because the source is wrapped in a function.
+    let mut parser =
+        match new_parser_from_source_str(&psess, filename, wrapped_source, StripTokens::Nothing) {
+            Ok(p) => p,
+            Err(errs) => {
+                errs.into_iter().for_each(|err| err.cancel());
+                reset_error_count(&psess);
+                return Err(());
+            }
+        };
 
     fn push_to_s(s: &mut String, source: &str, span: rustc_span::Span, prev_span_hi: &mut usize) {
         let extra_len = DOCTEST_CODE_WRAPPER.len();
diff --git a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
index 74283d7ba86..43bb9723555 100644
--- a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
@@ -8,6 +8,7 @@ use rustc_ast::{CoroutineKind, Fn, FnRetTy, Item, ItemKind};
 use rustc_errors::emitter::HumanEmitter;
 use rustc_errors::{Diag, DiagCtxt};
 use rustc_lint::LateContext;
+use rustc_parse::lexer::StripTokens;
 use rustc_parse::new_parser_from_source_str;
 use rustc_parse::parser::ForceCollect;
 use rustc_session::parse::ParseSess;
@@ -49,13 +50,14 @@ pub fn check(
                 let sm = Arc::new(SourceMap::new(FilePathMapping::empty()));
                 let psess = ParseSess::with_dcx(dcx, sm);
 
-                let mut parser = match new_parser_from_source_str(&psess, filename, code) {
-                    Ok(p) => p,
-                    Err(errs) => {
-                        errs.into_iter().for_each(Diag::cancel);
-                        return (false, test_attr_spans);
-                    },
-                };
+                let mut parser =
+                    match new_parser_from_source_str(&psess, filename, code, StripTokens::ShebangAndFrontmatter) {
+                        Ok(p) => p,
+                        Err(errs) => {
+                            errs.into_iter().for_each(Diag::cancel);
+                            return (false, test_attr_spans);
+                        },
+                    };
 
                 let mut relevant_main_found = false;
                 let mut eligible = true;
diff --git a/src/tools/rustfmt/src/parse/parser.rs b/src/tools/rustfmt/src/parse/parser.rs
index 2ec8769c45f..63c6c8c99d0 100644
--- a/src/tools/rustfmt/src/parse/parser.rs
+++ b/src/tools/rustfmt/src/parse/parser.rs
@@ -3,6 +3,7 @@ use std::path::{Path, PathBuf};
 
 use rustc_ast::{ast, attr};
 use rustc_errors::Diag;
+use rustc_parse::lexer::StripTokens;
 use rustc_parse::parser::Parser as RawParser;
 use rustc_parse::{exp, new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
 use rustc_span::{Span, sym};
@@ -64,11 +65,14 @@ impl<'a> ParserBuilder<'a> {
         input: Input,
     ) -> Result<RawParser<'a>, Vec<Diag<'a>>> {
         match input {
-            Input::File(ref file) => new_parser_from_file(psess, file, None),
+            Input::File(ref file) => {
+                new_parser_from_file(psess, file, StripTokens::ShebangAndFrontmatter, None)
+            }
             Input::Text(text) => new_parser_from_source_str(
                 psess,
                 rustc_span::FileName::Custom("stdin".to_owned()),
                 text,
+                StripTokens::ShebangAndFrontmatter,
             ),
         }
     }
@@ -104,8 +108,12 @@ impl<'a> Parser<'a> {
         span: Span,
     ) -> Result<(ast::AttrVec, ThinVec<Box<ast::Item>>, Span), ParserError> {
         let result = catch_unwind(AssertUnwindSafe(|| {
-            let mut parser =
-                unwrap_or_emit_fatal(new_parser_from_file(psess.inner(), path, Some(span)));
+            let mut parser = unwrap_or_emit_fatal(new_parser_from_file(
+                psess.inner(),
+                path,
+                StripTokens::ShebangAndFrontmatter,
+                Some(span),
+            ));
             match parser.parse_mod(exp!(Eof)) {
                 Ok((a, i, spans)) => Some((a, i, spans.inner_span)),
                 Err(e) => {
diff --git a/tests/ui-fulldeps/auxiliary/parser.rs b/tests/ui-fulldeps/auxiliary/parser.rs
index 6726969350d..6ee39e5130f 100644
--- a/tests/ui-fulldeps/auxiliary/parser.rs
+++ b/tests/ui-fulldeps/auxiliary/parser.rs
@@ -10,7 +10,7 @@ extern crate rustc_span;
 use rustc_ast::ast::{AttrKind, Attribute, DUMMY_NODE_ID, Expr};
 use rustc_ast::mut_visit::{self, MutVisitor};
 use rustc_ast::node_id::NodeId;
-use rustc_ast::token::{self, Token};
+use rustc_ast::token;
 use rustc_ast::tokenstream::{AttrTokenStream, AttrTokenTree, LazyAttrTokenStream};
 use rustc_errors::Diag;
 use rustc_parse::parser::Recovery;
@@ -23,6 +23,7 @@ pub fn parse_expr(psess: &ParseSess, source_code: &str) -> Option<Box<Expr>> {
         psess,
         FileName::anon_source_code(source_code),
         source_code.to_owned(),
+        rustc_parse::lexer::StripTokens::Nothing,
     ));
 
     let mut parser = parser.recovery(Recovery::Forbidden);
diff --git a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs
index 99cb5fc5aa1..df5f29e35fe 100644
--- a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs
+++ b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs
@@ -16,7 +16,7 @@ extern crate rustc_span;
 #[allow(unused_extern_crates)]
 extern crate rustc_driver;
 
-use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal};
+use rustc_parse::{lexer::StripTokens, new_parser_from_file, unwrap_or_emit_fatal};
 use rustc_session::parse::ParseSess;
 use std::path::Path;
 
@@ -34,6 +34,11 @@ fn parse() {
 
     let path = Path::new(file!());
     let path = path.canonicalize().unwrap();
-    let mut parser = unwrap_or_emit_fatal(new_parser_from_file(&psess, &path, None));
+    let mut parser = unwrap_or_emit_fatal(new_parser_from_file(
+        &psess,
+        &path,
+        StripTokens::ShebangAndFrontmatter,
+        None,
+    ));
     let _ = parser.parse_crate_mod();
 }
diff --git a/tests/ui/c-variadic/issue-86053-1.rs b/tests/ui/c-variadic/issue-86053-1.rs
index 537d0263adf..58dfee55cf8 100644
--- a/tests/ui/c-variadic/issue-86053-1.rs
+++ b/tests/ui/c-variadic/issue-86053-1.rs
@@ -13,6 +13,6 @@ fn ordering4 < 'a , 'b     > ( a :            ,   self , self ,   self ,
     //~| ERROR unexpected `self` parameter in function
     //~| ERROR unexpected `self` parameter in function
     //~| ERROR `...` must be the last argument of a C-variadic function
-    //~| ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+    //~| ERROR `...` is not supported for non-extern functions
     //~| ERROR cannot find type `F` in this scope
 }
diff --git a/tests/ui/c-variadic/issue-86053-1.stderr b/tests/ui/c-variadic/issue-86053-1.stderr
index b58016b5a81..adbc04d3a65 100644
--- a/tests/ui/c-variadic/issue-86053-1.stderr
+++ b/tests/ui/c-variadic/issue-86053-1.stderr
@@ -46,11 +46,13 @@ error: `...` must be the last argument of a C-variadic function
 LL |     self , ... ,   self ,   self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
    |            ^^^
 
-error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+error: `...` is not supported for non-extern functions
   --> $DIR/issue-86053-1.rs:11:36
    |
 LL |     self , ... ,   self ,   self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
    |                                    ^^^
+   |
+   = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
 
 error[E0412]: cannot find type `F` in this scope
   --> $DIR/issue-86053-1.rs:11:48
diff --git a/tests/ui/c-variadic/not-async.rs b/tests/ui/c-variadic/not-async.rs
new file mode 100644
index 00000000000..45a7e1f8972
--- /dev/null
+++ b/tests/ui/c-variadic/not-async.rs
@@ -0,0 +1,7 @@
+//@ edition: 2021
+#![feature(c_variadic)]
+#![crate_type = "lib"]
+
+async unsafe extern "C" fn cannot_be_async(x: isize, ...) {}
+//~^ ERROR functions cannot be both `async` and C-variadic
+//~| ERROR hidden type for `impl Future<Output = ()>` captures lifetime that does not appear in bounds
diff --git a/tests/ui/c-variadic/not-async.stderr b/tests/ui/c-variadic/not-async.stderr
new file mode 100644
index 00000000000..b8caf0d8bd8
--- /dev/null
+++ b/tests/ui/c-variadic/not-async.stderr
@@ -0,0 +1,19 @@
+error: functions cannot be both `async` and C-variadic
+  --> $DIR/not-async.rs:5:1
+   |
+LL | async unsafe extern "C" fn cannot_be_async(x: isize, ...) {}
+   | ^^^^^ `async` because of this                        ^^^ C-variadic because of this
+
+error[E0700]: hidden type for `impl Future<Output = ()>` captures lifetime that does not appear in bounds
+  --> $DIR/not-async.rs:5:59
+   |
+LL | async unsafe extern "C" fn cannot_be_async(x: isize, ...) {}
+   | --------------------------------------------------------- ^^
+   | |
+   | opaque type defined here
+   |
+   = note: hidden type `{async fn body of cannot_be_async()}` captures lifetime `'_`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0700`.
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs
index ad4fca8252d..eb6f4a32365 100644
--- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs
+++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs
@@ -53,9 +53,7 @@ extern "cmse-nonsecure-entry" fn trait_object(x: &dyn Trait) -> &dyn Trait {
     x
 }
 
-extern "cmse-nonsecure-entry" fn static_trait_object(
-    x: &'static dyn Trait,
-) -> &'static dyn Trait {
+extern "cmse-nonsecure-entry" fn static_trait_object(x: &'static dyn Trait) -> &'static dyn Trait {
     //~^ ERROR return value of `"cmse-nonsecure-entry"` function too large to pass via registers [E0798]
     x
 }
@@ -63,14 +61,12 @@ extern "cmse-nonsecure-entry" fn static_trait_object(
 #[repr(transparent)]
 struct WrapperTransparent<'a>(&'a dyn Trait);
 
-extern "cmse-nonsecure-entry" fn wrapped_trait_object(
-    x: WrapperTransparent,
-) -> WrapperTransparent {
+extern "cmse-nonsecure-entry" fn wrapped_trait_object(x: WrapperTransparent) -> WrapperTransparent {
     //~^ ERROR return value of `"cmse-nonsecure-entry"` function too large to pass via registers [E0798]
     x
 }
 
-extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) {
-    //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+unsafe extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) {
+    //~^ ERROR `...` is not supported for `extern "cmse-nonsecure-entry"` functions
     //~| ERROR requires `va_list` lang_item
 }
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr
index 7aeb6969feb..8937def9428 100644
--- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr
+++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr
@@ -1,8 +1,12 @@
-error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
-  --> $DIR/generics.rs:73:53
+error: `...` is not supported for `extern "cmse-nonsecure-entry"` functions
+  --> $DIR/generics.rs:69:60
    |
-LL | extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) {
-   |                                                     ^^^^^^
+LL | unsafe extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) {
+   |        -----------------------------                       ^^^^^^
+   |        |
+   |        `extern "cmse-nonsecure-entry"` because of this
+   |
+   = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
 
 error[E0798]: functions with the `"cmse-nonsecure-entry"` ABI cannot contain generics in their type
   --> $DIR/generics.rs:30:1
@@ -50,28 +54,28 @@ LL | extern "cmse-nonsecure-entry" fn trait_object(x: &dyn Trait) -> &dyn Trait
    = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
 
 error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers
-  --> $DIR/generics.rs:58:6
+  --> $DIR/generics.rs:56:80
    |
-LL | ) -> &'static dyn Trait {
-   |      ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers
+LL | extern "cmse-nonsecure-entry" fn static_trait_object(x: &'static dyn Trait) -> &'static dyn Trait {
+   |                                                                                ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers
    |
    = note: functions with the `"cmse-nonsecure-entry"` ABI must pass their result via the available return registers
    = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
 
 error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers
-  --> $DIR/generics.rs:68:6
+  --> $DIR/generics.rs:64:81
    |
-LL | ) -> WrapperTransparent {
-   |      ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers
+LL | extern "cmse-nonsecure-entry" fn wrapped_trait_object(x: WrapperTransparent) -> WrapperTransparent {
+   |                                                                                 ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers
    |
    = note: functions with the `"cmse-nonsecure-entry"` ABI must pass their result via the available return registers
    = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
 
 error: requires `va_list` lang_item
-  --> $DIR/generics.rs:73:53
+  --> $DIR/generics.rs:69:60
    |
-LL | extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) {
-   |                                                     ^^^^^^
+LL | unsafe extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) {
+   |                                                            ^^^^^^
 
 error: aborting due to 9 previous errors
 
diff --git a/tests/ui/deref/pin-deref-const.rs b/tests/ui/deref/pin-deref-const.rs
new file mode 100644
index 00000000000..6ed00177b23
--- /dev/null
+++ b/tests/ui/deref/pin-deref-const.rs
@@ -0,0 +1,79 @@
+// The purpose of this file is to track the error messages from Pin and DerefMut interacting.
+//
+// Identical to `pin-deref.rs` except for using unstable `const fn`.
+
+//@ check-fail
+
+#![feature(const_convert)]
+#![feature(const_trait_impl)]
+
+use std::ops::DerefMut;
+use std::pin::Pin;
+
+struct MyUnpinType {}
+
+impl MyUnpinType {
+    const fn at_self(&self) {}
+    const fn at_mut_self(&mut self) {}
+}
+
+struct MyPinType(core::marker::PhantomPinned);
+
+impl MyPinType {
+    const fn at_self(&self) {}
+    const fn at_mut_self(&mut self) {}
+}
+
+const fn call_mut_ref_unpin(mut r_unpin: Pin<&mut MyUnpinType>) {
+    r_unpin.at_self();
+    r_unpin.at_mut_self();
+}
+
+const fn call_ref_unpin(mut r_unpin: Pin<&MyUnpinType>) {
+    r_unpin.at_self();
+    r_unpin.at_mut_self(); //~ ERROR: cannot borrow data in dereference of `Pin<&MyUnpinType>` as mutable
+}
+
+const fn call_mut_ref_pin(mut r_pin: Pin<&mut MyPinType>) {
+    r_pin.at_self();
+    r_pin.at_mut_self(); //~ ERROR: cannot borrow data in dereference of `Pin<&mut MyPinType>` as mutable
+}
+
+const fn call_ref_pin(mut r_pin: Pin<&MyPinType>) {
+    r_pin.at_self();
+    r_pin.at_mut_self(); //~ ERROR: cannot borrow data in dereference of `Pin<&MyPinType>` as mutable
+}
+
+const fn coerce_unpin_rr<'a>(mut r_unpin: &'a mut Pin<&MyUnpinType>) -> &'a MyUnpinType {
+    r_unpin
+}
+
+const fn coerce_unpin_rm<'a>(mut r_unpin: &'a mut Pin<&MyUnpinType>) -> &'a mut MyUnpinType {
+    r_unpin //~ ERROR: cannot borrow data in dereference of `Pin<&MyUnpinType>` as mutable
+}
+
+const fn coerce_unpin_mr<'a>(mut r_unpin: &'a mut Pin<&mut MyUnpinType>) -> &'a MyUnpinType {
+    r_unpin
+}
+
+const fn coerce_unpin_mm<'a>(mut r_unpin: &'a mut Pin<&mut MyUnpinType>) -> &'a mut MyUnpinType {
+    r_unpin
+}
+
+const fn coerce_pin_rr<'a>(mut r_pin: &'a mut Pin<&MyPinType>) -> &'a MyPinType {
+    r_pin
+}
+
+const fn coerce_pin_rm<'a>(mut r_pin: &'a mut Pin<&MyPinType>) -> &'a mut MyPinType {
+    r_pin //~ ERROR: cannot borrow data in dereference of `Pin<&MyPinType>` as mutable
+}
+
+const fn coerce_pin_mr<'a>(mut r_pin: &'a mut Pin<&mut MyPinType>) -> &'a MyPinType {
+    r_pin
+}
+
+const fn coerce_pin_mm<'a>(mut r_pin: &'a mut Pin<&mut MyPinType>) -> &'a mut MyPinType {
+    r_pin //~ ERROR: cannot borrow data in dereference of `Pin<&mut MyPinType>` as mutable
+}
+
+fn main() {}
diff --git a/tests/ui/deref/pin-deref-const.stderr b/tests/ui/deref/pin-deref-const.stderr
new file mode 100644
index 00000000000..caa270e64ff
--- /dev/null
+++ b/tests/ui/deref/pin-deref-const.stderr
@@ -0,0 +1,51 @@
+error[E0596]: cannot borrow data in dereference of `Pin<&MyUnpinType>` as mutable
+  --> $DIR/pin-deref-const.rs:34:5
+   |
+LL |     r_unpin.at_mut_self();
+   |     ^^^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&MyUnpinType>`
+
+error[E0596]: cannot borrow data in dereference of `Pin<&mut MyPinType>` as mutable
+  --> $DIR/pin-deref-const.rs:39:5
+   |
+LL |     r_pin.at_mut_self();
+   |     ^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&mut MyPinType>`
+
+error[E0596]: cannot borrow data in dereference of `Pin<&MyPinType>` as mutable
+  --> $DIR/pin-deref-const.rs:44:5
+   |
+LL |     r_pin.at_mut_self();
+   |     ^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&MyPinType>`
+
+error[E0596]: cannot borrow data in dereference of `Pin<&MyUnpinType>` as mutable
+  --> $DIR/pin-deref-const.rs:52:5
+   |
+LL |     r_unpin
+   |     ^^^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&MyUnpinType>`
+
+error[E0596]: cannot borrow data in dereference of `Pin<&MyPinType>` as mutable
+  --> $DIR/pin-deref-const.rs:68:5
+   |
+LL |     r_pin
+   |     ^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&MyPinType>`
+
+error[E0596]: cannot borrow data in dereference of `Pin<&mut MyPinType>` as mutable
+  --> $DIR/pin-deref-const.rs:76:5
+   |
+LL |     r_pin
+   |     ^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&mut MyPinType>`
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/tests/ui/deref/pin-deref.rs b/tests/ui/deref/pin-deref.rs
new file mode 100644
index 00000000000..180831c9bc6
--- /dev/null
+++ b/tests/ui/deref/pin-deref.rs
@@ -0,0 +1,76 @@
+// The purpose of this file is to track the error messages from Pin and DerefMut interacting.
+//
+// Identical to `pin-deref-const.rs` except for being stable and not using `const fn`.
+
+//@ check-fail
+
+use std::ops::DerefMut;
+use std::pin::Pin;
+
+struct MyUnpinType {}
+
+impl MyUnpinType {
+    fn at_self(&self) {}
+    fn at_mut_self(&mut self) {}
+}
+
+struct MyPinType(core::marker::PhantomPinned);
+
+impl MyPinType {
+    fn at_self(&self) {}
+    fn at_mut_self(&mut self) {}
+}
+
+fn call_mut_ref_unpin(mut r_unpin: Pin<&mut MyUnpinType>) {
+    r_unpin.at_self();
+    r_unpin.at_mut_self();
+}
+
+fn call_ref_unpin(mut r_unpin: Pin<&MyUnpinType>) {
+    r_unpin.at_self();
+    r_unpin.at_mut_self(); //~ ERROR: cannot borrow data in dereference of `Pin<&MyUnpinType>` as mutable
+}
+
+fn call_mut_ref_pin(mut r_pin: Pin<&mut MyPinType>) {
+    r_pin.at_self();
+    r_pin.at_mut_self(); //~ ERROR: cannot borrow data in dereference of `Pin<&mut MyPinType>` as mutable
+}
+
+fn call_ref_pin(mut r_pin: Pin<&MyPinType>) {
+    r_pin.at_self();
+    r_pin.at_mut_self(); //~ ERROR: cannot borrow data in dereference of `Pin<&MyPinType>` as mutable
+}
+
+fn coerce_unpin_rr<'a>(mut r_unpin: &'a mut Pin<&MyUnpinType>) -> &'a MyUnpinType {
+    r_unpin
+}
+
+fn coerce_unpin_rm<'a>(mut r_unpin: &'a mut Pin<&MyUnpinType>) -> &'a mut MyUnpinType {
+    r_unpin //~ ERROR: cannot borrow data in dereference of `Pin<&MyUnpinType>` as mutable
+}
+
+fn coerce_unpin_mr<'a>(mut r_unpin: &'a mut Pin<&mut MyUnpinType>) -> &'a MyUnpinType {
+    r_unpin
+}
+
+fn coerce_unpin_mm<'a>(mut r_unpin: &'a mut Pin<&mut MyUnpinType>) -> &'a mut MyUnpinType {
+    r_unpin
+}
+
+fn coerce_pin_rr<'a>(mut r_pin: &'a mut Pin<&MyPinType>) -> &'a MyPinType {
+    r_pin
+}
+
+fn coerce_pin_rm<'a>(mut r_pin: &'a mut Pin<&MyPinType>) -> &'a mut MyPinType {
+    r_pin //~ ERROR: cannot borrow data in dereference of `Pin<&MyPinType>` as mutable
+}
+
+fn coerce_pin_mr<'a>(mut r_pin: &'a mut Pin<&mut MyPinType>) -> &'a MyPinType {
+    r_pin
+}
+
+fn coerce_pin_mm<'a>(mut r_pin: &'a mut Pin<&mut MyPinType>) -> &'a mut MyPinType {
+    r_pin //~ ERROR: cannot borrow data in dereference of `Pin<&mut MyPinType>` as mutable
+}
+
+fn main() {}
diff --git a/tests/ui/deref/pin-deref.stderr b/tests/ui/deref/pin-deref.stderr
new file mode 100644
index 00000000000..71277a10cdf
--- /dev/null
+++ b/tests/ui/deref/pin-deref.stderr
@@ -0,0 +1,51 @@
+error[E0596]: cannot borrow data in dereference of `Pin<&MyUnpinType>` as mutable
+  --> $DIR/pin-deref.rs:31:5
+   |
+LL |     r_unpin.at_mut_self();
+   |     ^^^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&MyUnpinType>`
+
+error[E0596]: cannot borrow data in dereference of `Pin<&mut MyPinType>` as mutable
+  --> $DIR/pin-deref.rs:36:5
+   |
+LL |     r_pin.at_mut_self();
+   |     ^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&mut MyPinType>`
+
+error[E0596]: cannot borrow data in dereference of `Pin<&MyPinType>` as mutable
+  --> $DIR/pin-deref.rs:41:5
+   |
+LL |     r_pin.at_mut_self();
+   |     ^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&MyPinType>`
+
+error[E0596]: cannot borrow data in dereference of `Pin<&MyUnpinType>` as mutable
+  --> $DIR/pin-deref.rs:49:5
+   |
+LL |     r_unpin
+   |     ^^^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&MyUnpinType>`
+
+error[E0596]: cannot borrow data in dereference of `Pin<&MyPinType>` as mutable
+  --> $DIR/pin-deref.rs:65:5
+   |
+LL |     r_pin
+   |     ^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&MyPinType>`
+
+error[E0596]: cannot borrow data in dereference of `Pin<&mut MyPinType>` as mutable
+  --> $DIR/pin-deref.rs:73:5
+   |
+LL |     r_pin
+   |     ^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&mut MyPinType>`
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/tests/ui/deref/pin-impl-deref.rs b/tests/ui/deref/pin-impl-deref.rs
new file mode 100644
index 00000000000..b1dc8dea3f2
--- /dev/null
+++ b/tests/ui/deref/pin-impl-deref.rs
@@ -0,0 +1,40 @@
+// The purpose of this file is to track the error messages from Pin and DerefMut interacting.
+
+//@ check-fail
+
+use std::ops::DerefMut;
+use std::pin::Pin;
+
+struct MyUnpinType {}
+
+impl MyUnpinType {
+    fn at_self(&self) {}
+    fn at_mut_self(&mut self) {}
+}
+
+struct MyPinType(core::marker::PhantomPinned);
+
+impl MyPinType {
+    fn at_self(&self) {}
+    fn at_mut_self(&mut self) {}
+}
+
+fn impl_deref_mut(_: impl DerefMut) {}
+fn unpin_impl_ref(r_unpin: Pin<&MyUnpinType>) {
+    impl_deref_mut(r_unpin)
+    //~^ ERROR: the trait bound `Pin<&MyUnpinType>: DerefMut` is not satisfied
+}
+fn unpin_impl_mut(r_unpin: Pin<&mut MyUnpinType>) {
+    impl_deref_mut(r_unpin)
+}
+fn pin_impl_ref(r_pin: Pin<&MyPinType>) {
+    impl_deref_mut(r_pin)
+    //~^ ERROR: `PhantomPinned` cannot be unpinned
+    //~| ERROR: the trait bound `Pin<&MyPinType>: DerefMut` is not satisfied
+}
+fn pin_impl_mut(r_pin: Pin<&mut MyPinType>) {
+    impl_deref_mut(r_pin)
+    //~^ ERROR: `PhantomPinned` cannot be unpinned
+}
+
+fn main() {}
diff --git a/tests/ui/deref/pin-impl-deref.stderr b/tests/ui/deref/pin-impl-deref.stderr
new file mode 100644
index 00000000000..106654641a1
--- /dev/null
+++ b/tests/ui/deref/pin-impl-deref.stderr
@@ -0,0 +1,85 @@
+error[E0277]: the trait bound `Pin<&MyUnpinType>: DerefMut` is not satisfied
+  --> $DIR/pin-impl-deref.rs:24:20
+   |
+LL |     impl_deref_mut(r_unpin)
+   |     -------------- ^^^^^^^ the trait `DerefMut` is not implemented for `Pin<&MyUnpinType>`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = note: required for `Pin<&MyUnpinType>` to implement `DerefMut`
+note: required by a bound in `impl_deref_mut`
+  --> $DIR/pin-impl-deref.rs:22:27
+   |
+LL | fn impl_deref_mut(_: impl DerefMut) {}
+   |                           ^^^^^^^^ required by this bound in `impl_deref_mut`
+help: consider mutably borrowing here
+   |
+LL |     impl_deref_mut(&mut r_unpin)
+   |                    ++++
+
+error[E0277]: the trait bound `Pin<&MyPinType>: DerefMut` is not satisfied
+  --> $DIR/pin-impl-deref.rs:31:20
+   |
+LL |     impl_deref_mut(r_pin)
+   |     -------------- ^^^^^ the trait `DerefMut` is not implemented for `Pin<&MyPinType>`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = note: required for `Pin<&MyPinType>` to implement `DerefMut`
+note: required by a bound in `impl_deref_mut`
+  --> $DIR/pin-impl-deref.rs:22:27
+   |
+LL | fn impl_deref_mut(_: impl DerefMut) {}
+   |                           ^^^^^^^^ required by this bound in `impl_deref_mut`
+help: consider mutably borrowing here
+   |
+LL |     impl_deref_mut(&mut r_pin)
+   |                    ++++
+
+error[E0277]: `PhantomPinned` cannot be unpinned
+  --> $DIR/pin-impl-deref.rs:31:20
+   |
+LL |     impl_deref_mut(r_pin)
+   |     -------------- ^^^^^ within `MyPinType`, the trait `Unpin` is not implemented for `PhantomPinned`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = note: consider using the `pin!` macro
+           consider using `Box::pin` if you need to access the pinned value outside of the current scope
+note: required because it appears within the type `MyPinType`
+  --> $DIR/pin-impl-deref.rs:15:8
+   |
+LL | struct MyPinType(core::marker::PhantomPinned);
+   |        ^^^^^^^^^
+   = note: required for `Pin<&MyPinType>` to implement `DerefMut`
+note: required by a bound in `impl_deref_mut`
+  --> $DIR/pin-impl-deref.rs:22:27
+   |
+LL | fn impl_deref_mut(_: impl DerefMut) {}
+   |                           ^^^^^^^^ required by this bound in `impl_deref_mut`
+
+error[E0277]: `PhantomPinned` cannot be unpinned
+  --> $DIR/pin-impl-deref.rs:36:20
+   |
+LL |     impl_deref_mut(r_pin)
+   |     -------------- ^^^^^ within `MyPinType`, the trait `Unpin` is not implemented for `PhantomPinned`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = note: consider using the `pin!` macro
+           consider using `Box::pin` if you need to access the pinned value outside of the current scope
+note: required because it appears within the type `MyPinType`
+  --> $DIR/pin-impl-deref.rs:15:8
+   |
+LL | struct MyPinType(core::marker::PhantomPinned);
+   |        ^^^^^^^^^
+   = note: required for `Pin<&mut MyPinType>` to implement `DerefMut`
+note: required by a bound in `impl_deref_mut`
+  --> $DIR/pin-impl-deref.rs:22:27
+   |
+LL | fn impl_deref_mut(_: impl DerefMut) {}
+   |                           ^^^^^^^^ required by this bound in `impl_deref_mut`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/feature-gates/feature-gate-c_variadic.rs b/tests/ui/feature-gates/feature-gate-c_variadic.rs
index 45c68842093..88d91dbd081 100644
--- a/tests/ui/feature-gates/feature-gate-c_variadic.rs
+++ b/tests/ui/feature-gates/feature-gate-c_variadic.rs
@@ -1,10 +1,10 @@
-#![crate_type="lib"]
+#![crate_type = "lib"]
 
-pub unsafe extern "C" fn test(_: i32, ap: ...) { }
+pub unsafe extern "C" fn test(_: i32, ap: ...) {}
 //~^ ERROR C-variadic functions are unstable
 
 trait Trait {
-    unsafe extern "C" fn trait_test(_: i32, ap: ...) { }
+    unsafe extern "C" fn trait_test(_: i32, ap: ...) {}
     //~^ ERROR C-variadic functions are unstable
-    //~| ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+    //~| ERROR associated functions cannot have a C variable argument list
 }
diff --git a/tests/ui/feature-gates/feature-gate-c_variadic.stderr b/tests/ui/feature-gates/feature-gate-c_variadic.stderr
index e30a2f1ede3..808aa20948d 100644
--- a/tests/ui/feature-gates/feature-gate-c_variadic.stderr
+++ b/tests/ui/feature-gates/feature-gate-c_variadic.stderr
@@ -1,14 +1,14 @@
-error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+error: associated functions cannot have a C variable argument list
   --> $DIR/feature-gate-c_variadic.rs:7:45
    |
-LL |     unsafe extern "C" fn trait_test(_: i32, ap: ...) { }
+LL |     unsafe extern "C" fn trait_test(_: i32, ap: ...) {}
    |                                             ^^^^^^^
 
 error[E0658]: C-variadic functions are unstable
   --> $DIR/feature-gate-c_variadic.rs:3:1
    |
-LL | pub unsafe extern "C" fn test(_: i32, ap: ...) { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | pub unsafe extern "C" fn test(_: i32, ap: ...) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: see issue #44930 <https://github.com/rust-lang/rust/issues/44930> for more information
    = help: add `#![feature(c_variadic)]` to the crate attributes to enable
@@ -17,8 +17,8 @@ LL | pub unsafe extern "C" fn test(_: i32, ap: ...) { }
 error[E0658]: C-variadic functions are unstable
   --> $DIR/feature-gate-c_variadic.rs:7:5
    |
-LL |     unsafe extern "C" fn trait_test(_: i32, ap: ...) { }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     unsafe extern "C" fn trait_test(_: i32, ap: ...) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: see issue #44930 <https://github.com/rust-lang/rust/issues/44930> for more information
    = help: add `#![feature(c_variadic)]` to the crate attributes to enable
diff --git a/tests/ui/fmt/ifmt-bad-arg.stderr b/tests/ui/fmt/ifmt-bad-arg.stderr
index 4344aee83c2..b565b836f21 100644
--- a/tests/ui/fmt/ifmt-bad-arg.stderr
+++ b/tests/ui/fmt/ifmt-bad-arg.stderr
@@ -62,6 +62,11 @@ LL |     format!("", 1, 2);
    |             |   |
    |             |   argument never used
    |             multiple missing formatting specifiers
+   |
+help: format specifiers use curly braces, consider adding 2 format specifiers
+   |
+LL |     format!("{}{}", 1, 2);
+   |              ++++
 
 error: argument never used
   --> $DIR/ifmt-bad-arg.rs:33:22
@@ -102,6 +107,11 @@ LL |     format!("", foo=2);
    |             --      ^ named argument never used
    |             |
    |             formatting specifier missing
+   |
+help: format specifiers use curly braces, consider adding a format specifier
+   |
+LL |     format!("{}", foo=2);
+   |              ++
 
 error: multiple unused formatting arguments
   --> $DIR/ifmt-bad-arg.rs:38:32
@@ -111,6 +121,8 @@ LL |     format!("{} {}", 1, 2, foo=1, bar=2);
    |             |                  |
    |             |                  named argument never used
    |             multiple missing formatting specifiers
+   |
+   = note: consider adding 2 format specifiers
 
 error: duplicate argument named `foo`
   --> $DIR/ifmt-bad-arg.rs:40:29
diff --git a/tests/ui/frontmatter/auxiliary/expr.rs b/tests/ui/frontmatter/auxiliary/expr.rs
new file mode 100644
index 00000000000..5f694110666
--- /dev/null
+++ b/tests/ui/frontmatter/auxiliary/expr.rs
@@ -0,0 +1,4 @@
+---
+-
+---
+1
diff --git a/tests/ui/frontmatter/auxiliary/makro.rs b/tests/ui/frontmatter/auxiliary/makro.rs
index 70707b27bff..1d64fa44bd3 100644
--- a/tests/ui/frontmatter/auxiliary/makro.rs
+++ b/tests/ui/frontmatter/auxiliary/makro.rs
@@ -1,8 +1,20 @@
 extern crate proc_macro;
-use proc_macro::TokenStream;
+use proc_macro::{Literal, TokenStream};
 
 #[proc_macro]
 pub fn check(_: TokenStream) -> TokenStream {
+    // In the following test cases, the `---` may look like the start of frontmatter but it is not!
+    // That's because it would be backward incompatible to interpret them as such in the latest
+    // stable edition. That's not only the case due to the feature gate error but also due to the
+    // fact that we "eagerly" emit errors on malformed frontmatter.
+
+    // issue: <https://github.com/rust-lang/rust/issues/145520>
+    _ = "---".parse::<TokenStream>();
+    // Just a sequence of regular Rust punctuation tokens.
     assert_eq!(6, "---\n---".parse::<TokenStream>().unwrap().into_iter().count());
+
+    // issue: <https://github.com/rust-lang/rust/issues/146132>
+    assert!("---".parse::<Literal>().is_err());
+
     Default::default()
 }
diff --git a/tests/ui/frontmatter/include-in-expr-ctxt.rs b/tests/ui/frontmatter/include-in-expr-ctxt.rs
new file mode 100644
index 00000000000..7b02c9cb8a5
--- /dev/null
+++ b/tests/ui/frontmatter/include-in-expr-ctxt.rs
@@ -0,0 +1,9 @@
+// Check that an expr-ctxt `include` doesn't try to parse frontmatter and instead
+// treats it as a regular Rust token sequence.
+//@ check-pass
+#![expect(double_negations)]
+
+fn main() {
+    // issue: <https://github.com/rust-lang/rust/issues/145945>
+    const _: () = assert!(-1 == include!("auxiliary/expr.rs"));
+}
diff --git a/tests/ui/frontmatter/include-in-item-ctxt.rs b/tests/ui/frontmatter/include-in-item-ctxt.rs
new file mode 100644
index 00000000000..c8455bc49ab
--- /dev/null
+++ b/tests/ui/frontmatter/include-in-item-ctxt.rs
@@ -0,0 +1,10 @@
+// Ensure that in item ctxts we can `include` files that contain frontmatter.
+//@ check-pass
+
+#![feature(frontmatter)]
+
+include!("auxiliary/lib.rs");
+
+fn main() {
+    foo(1);
+}
diff --git a/tests/ui/frontmatter/included-frontmatter.rs b/tests/ui/frontmatter/included-frontmatter.rs
deleted file mode 100644
index 57616cd1228..00000000000
--- a/tests/ui/frontmatter/included-frontmatter.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-#![feature(frontmatter)]
-
-//@ check-pass
-
-include!("auxiliary/lib.rs");
-
-// auxiliary/lib.rs contains a frontmatter. Ensure that we can use them in an
-// `include!` macro.
-
-fn main() {
-    foo(1);
-}
diff --git a/tests/ui/frontmatter/proc-macro-observer.rs b/tests/ui/frontmatter/proc-macro-observer.rs
index b1cc1460933..6c4c8c57289 100644
--- a/tests/ui/frontmatter/proc-macro-observer.rs
+++ b/tests/ui/frontmatter/proc-macro-observer.rs
@@ -2,10 +2,9 @@
 //@ proc-macro: makro.rs
 //@ edition: 2021
 
-makro::check!();
+// Check that a proc-macro doesn't try to parse frontmatter and instead treats
+// it as a regular Rust token sequence. See `auxiliary/makro.rs` for details.
 
-// checks that a proc-macro doesn't know or parse frontmatters at all and instead treats
-// it as normal Rust code.
-// see auxiliary/makro.rs for how it is tested.
+makro::check!();
 
 fn main() {}
diff --git a/tests/ui/inference/note-and-explain-ReVar-124973.rs b/tests/ui/inference/note-and-explain-ReVar-124973.rs
index f1e24645636..aa4b909fa76 100644
--- a/tests/ui/inference/note-and-explain-ReVar-124973.rs
+++ b/tests/ui/inference/note-and-explain-ReVar-124973.rs
@@ -3,6 +3,7 @@
 #![feature(c_variadic)]
 
 async unsafe extern "C" fn multiple_named_lifetimes<'a, 'b>(_: u8, ...) {}
-//~^ ERROR hidden type for `impl Future<Output = ()>` captures lifetime that does not appear in bounds
+//~^ ERROR functions cannot be both `async` and C-variadic
+//~| ERROR hidden type for `impl Future<Output = ()>` captures lifetime that does not appear in bounds
 
 fn main() {}
diff --git a/tests/ui/inference/note-and-explain-ReVar-124973.stderr b/tests/ui/inference/note-and-explain-ReVar-124973.stderr
index 574f6508e4c..964fbc4a4fb 100644
--- a/tests/ui/inference/note-and-explain-ReVar-124973.stderr
+++ b/tests/ui/inference/note-and-explain-ReVar-124973.stderr
@@ -1,3 +1,9 @@
+error: functions cannot be both `async` and C-variadic
+  --> $DIR/note-and-explain-ReVar-124973.rs:5:1
+   |
+LL | async unsafe extern "C" fn multiple_named_lifetimes<'a, 'b>(_: u8, ...) {}
+   | ^^^^^ `async` because of this                                      ^^^ C-variadic because of this
+
 error[E0700]: hidden type for `impl Future<Output = ()>` captures lifetime that does not appear in bounds
   --> $DIR/note-and-explain-ReVar-124973.rs:5:73
    |
@@ -8,6 +14,6 @@ LL | async unsafe extern "C" fn multiple_named_lifetimes<'a, 'b>(_: u8, ...) {}
    |
    = note: hidden type `{async fn body of multiple_named_lifetimes<'a, 'b>()}` captures lifetime `'_`
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0700`.
diff --git a/tests/ui/macros/format-unused-lables.stderr b/tests/ui/macros/format-unused-lables.stderr
index fad87fa2aee..90eed8dd86b 100644
--- a/tests/ui/macros/format-unused-lables.stderr
+++ b/tests/ui/macros/format-unused-lables.stderr
@@ -7,6 +7,11 @@ LL |     println!("Test", 123, 456, 789);
    |              |       |    argument never used
    |              |       argument never used
    |              multiple missing formatting specifiers
+   |
+help: format specifiers use curly braces, consider adding 3 format specifiers
+   |
+LL |     println!("Test{}{}{}", 123, 456, 789);
+   |                   ++++++
 
 error: multiple unused formatting arguments
   --> $DIR/format-unused-lables.rs:6:9
@@ -19,6 +24,11 @@ LL |         456,
    |         ^^^ argument never used
 LL |         789
    |         ^^^ argument never used
+   |
+help: format specifiers use curly braces, consider adding 3 format specifiers
+   |
+LL |     println!("Test2{}{}{}",
+   |                    ++++++
 
 error: named argument never used
   --> $DIR/format-unused-lables.rs:11:35
@@ -27,6 +37,11 @@ LL |     println!("Some stuff", UNUSED="args");
    |              ------------         ^^^^^^ named argument never used
    |              |
    |              formatting specifier missing
+   |
+help: format specifiers use curly braces, consider adding a format specifier
+   |
+LL |     println!("Some stuff{}", UNUSED="args");
+   |                         ++
 
 error: multiple unused formatting arguments
   --> $DIR/format-unused-lables.rs:14:9
diff --git a/tests/ui/mir/issue-83499-input-output-iteration-ice.rs b/tests/ui/mir/issue-83499-input-output-iteration-ice.rs
index 9277994d9b3..dc0d14bf9d6 100644
--- a/tests/ui/mir/issue-83499-input-output-iteration-ice.rs
+++ b/tests/ui/mir/issue-83499-input-output-iteration-ice.rs
@@ -4,7 +4,6 @@
 
 fn main() {}
 
-fn foo(_: Bar, ...) -> impl {}
-//~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
-//~| ERROR cannot find type `Bar` in this scope
+unsafe extern "C" fn foo(_: Bar, ...) -> impl {}
+//~^ ERROR cannot find type `Bar` in this scope
 //~| ERROR at least one trait must be specified
diff --git a/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr b/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr
index 4a1aa49eb6e..31a393e7367 100644
--- a/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr
+++ b/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr
@@ -1,21 +1,15 @@
-error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
-  --> $DIR/issue-83499-input-output-iteration-ice.rs:7:16
-   |
-LL | fn foo(_: Bar, ...) -> impl {}
-   |                ^^^
-
 error: at least one trait must be specified
-  --> $DIR/issue-83499-input-output-iteration-ice.rs:7:24
+  --> $DIR/issue-83499-input-output-iteration-ice.rs:7:42
    |
-LL | fn foo(_: Bar, ...) -> impl {}
-   |                        ^^^^
+LL | unsafe extern "C" fn foo(_: Bar, ...) -> impl {}
+   |                                          ^^^^
 
 error[E0412]: cannot find type `Bar` in this scope
-  --> $DIR/issue-83499-input-output-iteration-ice.rs:7:11
+  --> $DIR/issue-83499-input-output-iteration-ice.rs:7:29
    |
-LL | fn foo(_: Bar, ...) -> impl {}
-   |           ^^^ not found in this scope
+LL | unsafe extern "C" fn foo(_: Bar, ...) -> impl {}
+   |                             ^^^ not found in this scope
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0412`.
diff --git a/tests/ui/mir/unsized-extern-static.stderr b/tests/ui/mir/unsized-extern-static.stderr
index 93aed3549d7..c0810e650ef 100644
--- a/tests/ui/mir/unsized-extern-static.stderr
+++ b/tests/ui/mir/unsized-extern-static.stderr
@@ -5,6 +5,11 @@ LL |     println!("C", unsafe { &symbol });
    |              ---  ^^^^^^^^^^^^^^^^^^ argument never used
    |              |
    |              formatting specifier missing
+   |
+help: format specifiers use curly braces, consider adding a format specifier
+   |
+LL |     println!("C{}", unsafe { &symbol });
+   |                ++
 
 error[E0277]: the size for values of type `[i8]` cannot be known at compilation time
   --> $DIR/unsized-extern-static.rs:6:5
diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs
index 243924e6c53..4db056f15a5 100644
--- a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs
+++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs
@@ -4,25 +4,28 @@
 fn main() {}
 
 fn f1_1(x: isize, ...) {}
-//~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+//~^ ERROR `...` is not supported for non-extern functions
 
 fn f1_2(...) {}
-//~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+//~^ ERROR `...` is not supported for non-extern functions
+
+unsafe extern "Rust" fn f1_3(...) {}
+//~^ ERROR `...` is not supported for `extern "Rust"` functions
 
 extern "C" fn f2_1(x: isize, ...) {}
-//~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+//~^ ERROR functions with a C variable argument list must be unsafe
 
 extern "C" fn f2_2(...) {}
-//~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+//~^ ERROR functions with a C variable argument list must be unsafe
 
 extern "C" fn f2_3(..., x: isize) {}
 //~^ ERROR `...` must be the last argument of a C-variadic function
 
 extern "C" fn f3_1(x: isize, ...) {}
-//~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+//~^ ERROR functions with a C variable argument list must be unsafe
 
 extern "C" fn f3_2(...) {}
-//~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+//~^ ERROR functions with a C variable argument list must be unsafe
 
 extern "C" fn f3_3(..., x: isize) {}
 //~^ ERROR `...` must be the last argument of a C-variadic function
@@ -33,12 +36,12 @@ const unsafe extern "C" fn f4_1(x: isize, ...) {}
 
 const extern "C" fn f4_2(x: isize, ...) {}
 //~^ ERROR functions cannot be both `const` and C-variadic
-//~| ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+//~| ERROR functions with a C variable argument list must be unsafe
 //~| ERROR destructor of `VaListImpl<'_>` cannot be evaluated at compile-time
 
 const extern "C" fn f4_3(..., x: isize, ...) {}
 //~^ ERROR functions cannot be both `const` and C-variadic
-//~| ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+//~| ERROR functions with a C variable argument list must be unsafe
 //~| ERROR `...` must be the last argument of a C-variadic function
 
 extern "C" {
@@ -50,30 +53,30 @@ struct X;
 
 impl X {
     fn i_f1(x: isize, ...) {}
-    //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+    //~^ ERROR associated functions cannot have a C variable argument list
     fn i_f2(...) {}
-    //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+    //~^ ERROR associated functions cannot have a C variable argument list
     fn i_f3(..., x: isize, ...) {}
-    //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+    //~^ ERROR associated functions cannot have a C variable argument list
     //~| ERROR `...` must be the last argument of a C-variadic function
     fn i_f4(..., x: isize, ...) {}
-    //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+    //~^ ERROR associated functions cannot have a C variable argument list
     //~| ERROR `...` must be the last argument of a C-variadic function
     const fn i_f5(x: isize, ...) {}
-    //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+    //~^ ERROR associated functions cannot have a C variable argument list
     //~| ERROR functions cannot be both `const` and C-variadic
     //~| ERROR destructor of `VaListImpl<'_>` cannot be evaluated at compile-time
 }
 
 trait T {
     fn t_f1(x: isize, ...) {}
-    //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+    //~^ ERROR associated functions cannot have a C variable argument list
     fn t_f2(x: isize, ...);
-    //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+    //~^ ERROR associated functions cannot have a C variable argument list
     fn t_f3(...) {}
-    //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+    //~^ ERROR associated functions cannot have a C variable argument list
     fn t_f4(...);
-    //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+    //~^ ERROR associated functions cannot have a C variable argument list
     fn t_f5(..., x: isize) {}
     //~^ ERROR `...` must be the last argument of a C-variadic function
     fn t_f6(..., x: isize);
diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr
index 5c55cc38b56..0cd78318de6 100644
--- a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr
+++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr
@@ -1,181 +1,225 @@
-error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+error: `...` is not supported for non-extern functions
   --> $DIR/variadic-ffi-semantic-restrictions.rs:6:19
    |
 LL | fn f1_1(x: isize, ...) {}
    |                   ^^^
+   |
+   = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
 
-error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+error: `...` is not supported for non-extern functions
   --> $DIR/variadic-ffi-semantic-restrictions.rs:9:9
    |
 LL | fn f1_2(...) {}
    |         ^^^
+   |
+   = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
 
-error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
+error: `...` is not supported for `extern "Rust"` functions
   --> $DIR/variadic-ffi-semantic-restrictions.rs:12:30
    |
+LL | unsafe extern "Rust" fn f1_3(...) {}
+   |        -------------         ^^^
+   |        |
+   |        `extern "Rust"` because of this
+   |
+   = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
+
+error: functions with a C variable argument list must be unsafe
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:15:30
+   |
 LL | extern "C" fn f2_1(x: isize, ...) {}
    |                              ^^^
+   |
+help: add the `unsafe` keyword to this definition
+   |
+LL | unsafe extern "C" fn f2_1(x: isize, ...) {}
+   | ++++++
 
-error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:15:20
+error: functions with a C variable argument list must be unsafe
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:18:20
    |
 LL | extern "C" fn f2_2(...) {}
    |                    ^^^
+   |
+help: add the `unsafe` keyword to this definition
+   |
+LL | unsafe extern "C" fn f2_2(...) {}
+   | ++++++
 
 error: `...` must be the last argument of a C-variadic function
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:18:20
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:21:20
    |
 LL | extern "C" fn f2_3(..., x: isize) {}
    |                    ^^^
 
-error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:21:30
+error: functions with a C variable argument list must be unsafe
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:24:30
    |
 LL | extern "C" fn f3_1(x: isize, ...) {}
    |                              ^^^
+   |
+help: add the `unsafe` keyword to this definition
+   |
+LL | unsafe extern "C" fn f3_1(x: isize, ...) {}
+   | ++++++
 
-error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:24:20
+error: functions with a C variable argument list must be unsafe
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:27:20
    |
 LL | extern "C" fn f3_2(...) {}
    |                    ^^^
+   |
+help: add the `unsafe` keyword to this definition
+   |
+LL | unsafe extern "C" fn f3_2(...) {}
+   | ++++++
 
 error: `...` must be the last argument of a C-variadic function
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:27:20
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:30:20
    |
 LL | extern "C" fn f3_3(..., x: isize) {}
    |                    ^^^
 
 error: functions cannot be both `const` and C-variadic
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:30:1
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:33:1
    |
 LL | const unsafe extern "C" fn f4_1(x: isize, ...) {}
    | ^^^^^ `const` because of this             ^^^ C-variadic because of this
 
 error: functions cannot be both `const` and C-variadic
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:34:1
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:37:1
    |
 LL | const extern "C" fn f4_2(x: isize, ...) {}
    | ^^^^^ `const` because of this      ^^^ C-variadic because of this
 
-error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:34:36
+error: functions with a C variable argument list must be unsafe
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:37:36
    |
 LL | const extern "C" fn f4_2(x: isize, ...) {}
    |                                    ^^^
+   |
+help: add the `unsafe` keyword to this definition
+   |
+LL | const unsafe extern "C" fn f4_2(x: isize, ...) {}
+   |       ++++++
 
 error: `...` must be the last argument of a C-variadic function
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:39:26
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:42:26
    |
 LL | const extern "C" fn f4_3(..., x: isize, ...) {}
    |                          ^^^
 
 error: functions cannot be both `const` and C-variadic
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:39:1
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:42:1
    |
 LL | const extern "C" fn f4_3(..., x: isize, ...) {}
    | ^^^^^ `const` because of this           ^^^ C-variadic because of this
 
-error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:39:41
+error: functions with a C variable argument list must be unsafe
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:42:41
    |
 LL | const extern "C" fn f4_3(..., x: isize, ...) {}
    |                                         ^^^
+   |
+help: add the `unsafe` keyword to this definition
+   |
+LL | const unsafe extern "C" fn f4_3(..., x: isize, ...) {}
+   |       ++++++
 
 error: `...` must be the last argument of a C-variadic function
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:45:13
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:48:13
    |
 LL |     fn e_f2(..., x: isize);
    |             ^^^
 
-error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:52:23
+error: associated functions cannot have a C variable argument list
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:55:23
    |
 LL |     fn i_f1(x: isize, ...) {}
    |                       ^^^
 
-error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:54:13
+error: associated functions cannot have a C variable argument list
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:57:13
    |
 LL |     fn i_f2(...) {}
    |             ^^^
 
 error: `...` must be the last argument of a C-variadic function
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:56:13
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:59:13
    |
 LL |     fn i_f3(..., x: isize, ...) {}
    |             ^^^
 
-error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:56:28
+error: associated functions cannot have a C variable argument list
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:59:28
    |
 LL |     fn i_f3(..., x: isize, ...) {}
    |                            ^^^
 
 error: `...` must be the last argument of a C-variadic function
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:59:13
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:62:13
    |
 LL |     fn i_f4(..., x: isize, ...) {}
    |             ^^^
 
-error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:59:28
+error: associated functions cannot have a C variable argument list
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:62:28
    |
 LL |     fn i_f4(..., x: isize, ...) {}
    |                            ^^^
 
 error: functions cannot be both `const` and C-variadic
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:62:5
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:65:5
    |
 LL |     const fn i_f5(x: isize, ...) {}
    |     ^^^^^                   ^^^ C-variadic because of this
    |     |
    |     `const` because of this
 
-error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:62:29
+error: associated functions cannot have a C variable argument list
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:65:29
    |
 LL |     const fn i_f5(x: isize, ...) {}
    |                             ^^^
 
-error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:69:23
+error: associated functions cannot have a C variable argument list
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:72:23
    |
 LL |     fn t_f1(x: isize, ...) {}
    |                       ^^^
 
-error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:71:23
+error: associated functions cannot have a C variable argument list
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:74:23
    |
 LL |     fn t_f2(x: isize, ...);
    |                       ^^^
 
-error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:73:13
+error: associated functions cannot have a C variable argument list
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:76:13
    |
 LL |     fn t_f3(...) {}
    |             ^^^
 
-error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:75:13
+error: associated functions cannot have a C variable argument list
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:78:13
    |
 LL |     fn t_f4(...);
    |             ^^^
 
 error: `...` must be the last argument of a C-variadic function
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:77:13
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:80:13
    |
 LL |     fn t_f5(..., x: isize) {}
    |             ^^^
 
 error: `...` must be the last argument of a C-variadic function
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:79:13
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:82:13
    |
 LL |     fn t_f6(..., x: isize);
    |             ^^^
 
 error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:30:43
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:33:43
    |
 LL | const unsafe extern "C" fn f4_1(x: isize, ...) {}
    |                                           ^^^   - value is dropped here
@@ -183,7 +227,7 @@ LL | const unsafe extern "C" fn f4_1(x: isize, ...) {}
    |                                           the destructor for this type cannot be evaluated in constant functions
 
 error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:34:36
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:37:36
    |
 LL | const extern "C" fn f4_2(x: isize, ...) {}
    |                                    ^^^   - value is dropped here
@@ -191,13 +235,13 @@ LL | const extern "C" fn f4_2(x: isize, ...) {}
    |                                    the destructor for this type cannot be evaluated in constant functions
 
 error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:62:29
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:65:29
    |
 LL |     const fn i_f5(x: isize, ...) {}
    |                             ^^^   - value is dropped here
    |                             |
    |                             the destructor for this type cannot be evaluated in constant functions
 
-error: aborting due to 32 previous errors
+error: aborting due to 33 previous errors
 
 For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/suggestions/missing-format-specifiers-issue-68293.rs b/tests/ui/suggestions/missing-format-specifiers-issue-68293.rs
new file mode 100644
index 00000000000..29799624d78
--- /dev/null
+++ b/tests/ui/suggestions/missing-format-specifiers-issue-68293.rs
@@ -0,0 +1,35 @@
+fn no_format_specifier_two_unused_args() {
+    println!("Hello", "World");
+    //~^ ERROR argument never used
+    //~| NOTE formatting specifier missing
+    //~| NOTE argument never used
+    //~| HELP format specifiers use curly braces, consider adding a format specifier
+}
+
+fn no_format_specifier_multiple_unused_args() {
+    println!("list: ", 1, 2, 3);
+    //~^ ERROR multiple unused formatting arguments
+    //~| NOTE multiple missing formatting specifiers
+    //~| NOTE argument never used
+    //~| NOTE argument never used
+    //~| NOTE argument never used
+    //~| HELP format specifiers use curly braces, consider adding 3 format specifiers
+}
+
+fn missing_format_specifiers_one_unused_arg() {
+    println!("list: {}, {}", 1, 2, 3);
+    //~^ ERROR argument never used
+    //~| NOTE formatting specifier missing
+    //~| NOTE argument never used
+}
+
+fn missing_format_specifiers_multiple_unused_args() {
+    println!("list: {}", 1, 2, 3);
+    //~^ ERROR multiple unused formatting arguments
+    //~| NOTE multiple missing formatting specifiers
+    //~| NOTE argument never used
+    //~| NOTE argument never used
+    //~| NOTE consider adding 2 format specifiers
+}
+
+fn main() { }
diff --git a/tests/ui/suggestions/missing-format-specifiers-issue-68293.stderr b/tests/ui/suggestions/missing-format-specifiers-issue-68293.stderr
new file mode 100644
index 00000000000..081409789f5
--- /dev/null
+++ b/tests/ui/suggestions/missing-format-specifiers-issue-68293.stderr
@@ -0,0 +1,49 @@
+error: argument never used
+  --> $DIR/missing-format-specifiers-issue-68293.rs:2:23
+   |
+LL |     println!("Hello", "World");
+   |              -------  ^^^^^^^ argument never used
+   |              |
+   |              formatting specifier missing
+   |
+help: format specifiers use curly braces, consider adding a format specifier
+   |
+LL |     println!("Hello{}", "World");
+   |                    ++
+
+error: multiple unused formatting arguments
+  --> $DIR/missing-format-specifiers-issue-68293.rs:10:24
+   |
+LL |     println!("list: ", 1, 2, 3);
+   |              --------  ^  ^  ^ argument never used
+   |              |         |  |
+   |              |         |  argument never used
+   |              |         argument never used
+   |              multiple missing formatting specifiers
+   |
+help: format specifiers use curly braces, consider adding 3 format specifiers
+   |
+LL |     println!("list: {}{}{}", 1, 2, 3);
+   |                     ++++++
+
+error: argument never used
+  --> $DIR/missing-format-specifiers-issue-68293.rs:20:36
+   |
+LL |     println!("list: {}, {}", 1, 2, 3);
+   |              --------------        ^ argument never used
+   |              |
+   |              formatting specifier missing
+
+error: multiple unused formatting arguments
+  --> $DIR/missing-format-specifiers-issue-68293.rs:27:29
+   |
+LL |     println!("list: {}", 1, 2, 3);
+   |              ----------     ^  ^ argument never used
+   |              |              |
+   |              |              argument never used
+   |              multiple missing formatting specifiers
+   |
+   = note: consider adding 2 format specifiers
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/trait-bounds/more_maybe_bounds.rs b/tests/ui/trait-bounds/more_maybe_bounds.rs
index d367dd5b299..ddd4313bd5e 100644
--- a/tests/ui/trait-bounds/more_maybe_bounds.rs
+++ b/tests/ui/trait-bounds/more_maybe_bounds.rs
@@ -21,6 +21,20 @@ fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
 
 // FIXME: `?Trait1` should be rejected, `Trait1` isn't marked `#[lang = "default_traitN"]`.
 fn baz<T>() where T: Iterator<Item: ?Trait1> {}
+//~^ ERROR this relaxed bound is not permitted here
+
+struct S1<T>(T);
+
+impl<T> S1<T> {
+    fn f() where T: ?Trait1 {}
+    //~^ ERROR this relaxed bound is not permitted here
+}
+
+trait Trait5<'a> {}
+
+struct S2<T>(T) where for<'a> T: ?Trait5<'a>;
+//~^ ERROR this relaxed bound is not permitted here
+//~| ERROR bound modifier `?` can only be applied to default traits like `Sized`
 
 struct S;
 impl !Trait2 for S {}
diff --git a/tests/ui/trait-bounds/more_maybe_bounds.stderr b/tests/ui/trait-bounds/more_maybe_bounds.stderr
index 8dd83fc7728..0d78cfd5820 100644
--- a/tests/ui/trait-bounds/more_maybe_bounds.stderr
+++ b/tests/ui/trait-bounds/more_maybe_bounds.stderr
@@ -1,3 +1,27 @@
+error: this relaxed bound is not permitted here
+  --> $DIR/more_maybe_bounds.rs:23:37
+   |
+LL | fn baz<T>() where T: Iterator<Item: ?Trait1> {}
+   |                                     ^^^^^^^
+   |
+   = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item
+
+error: this relaxed bound is not permitted here
+  --> $DIR/more_maybe_bounds.rs:29:21
+   |
+LL |     fn f() where T: ?Trait1 {}
+   |                     ^^^^^^^
+   |
+   = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item
+
+error: this relaxed bound is not permitted here
+  --> $DIR/more_maybe_bounds.rs:35:34
+   |
+LL | struct S2<T>(T) where for<'a> T: ?Trait5<'a>;
+   |                                  ^^^^^^^^^^^
+   |
+   = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item
+
 error: bound modifier `?` can only be applied to default traits like `Sized`
   --> $DIR/more_maybe_bounds.rs:17:20
    |
@@ -16,5 +40,11 @@ error: bound modifier `?` can only be applied to default traits like `Sized`
 LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
    |                                        ^^^^^^^
 
-error: aborting due to 3 previous errors
+error: bound modifier `?` can only be applied to default traits like `Sized`
+  --> $DIR/more_maybe_bounds.rs:35:34
+   |
+LL | struct S2<T>(T) where for<'a> T: ?Trait5<'a>;
+   |                                  ^^^^^^^^^^^
+
+error: aborting due to 7 previous errors
 
diff --git a/tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs b/tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs
deleted file mode 100644
index 745b6ee9bc5..00000000000
--- a/tests/ui/traits/default_auto_traits/backward-compatible-lazy-bounds-pass.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-//@ check-pass
-//@ compile-flags: -Zexperimental-default-bounds
-
-#![feature(auto_traits, lang_items, no_core, rustc_attrs, trait_alias)]
-#![no_std]
-#![no_core]
-
-#[lang = "pointee_sized"]
-trait PointeeSized {}
-
-#[lang = "meta_sized"]
-trait MetaSized: PointeeSized {}
-
-#[lang = "sized"]
-trait Sized: MetaSized {}
-
-#[lang = "default_trait1"]
-auto trait DefaultTrait1 {}
-
-#[lang = "default_trait2"]
-auto trait DefaultTrait2 {}
-
-trait Trait<Rhs: ?Sized = Self> {}
-trait Trait1 : Trait {}
-
-trait Trait2 {
-    type Type;
-}
-trait Trait3<T> = Trait2<Type = T>;
-
-fn main() {}
diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs
index e7cca41a47e..2e1a5d2424b 100644
--- a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs
+++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs
@@ -13,32 +13,37 @@
 #![no_core]
 
 #[lang = "pointee_sized"]
-trait PointeeSized {}
+trait PointeeSized: ?Leak {}
 
 #[lang = "meta_sized"]
-trait MetaSized: PointeeSized {}
+trait MetaSized: PointeeSized + ?Leak {}
 
 #[lang = "sized"]
-trait Sized: MetaSized {}
+trait Sized: MetaSized + ?Leak {}
 
 #[lang = "copy"]
-pub trait Copy {}
+pub trait Copy: ?Leak {}
 impl<'a, T: ?Sized> Copy for &'a T {}
 
 #[lang = "legacy_receiver"]
-trait Receiver {}
+trait Receiver: ?Leak {}
 impl<T: ?Sized + ?Leak> Receiver for &T {}
+impl<T: ?Sized + ?Leak> Receiver for &mut T {}
 
 #[lang = "unsize"]
-trait Unsize<T: ?Sized + ?Leak> {}
+trait Unsize<T: ?Sized + ?Leak>: ?Leak {}
 
 #[lang = "coerce_unsized"]
-trait CoerceUnsized<T: ?Leak + ?Sized> {}
+trait CoerceUnsized<T: ?Leak + ?Sized>: ?Leak {}
 impl<'a, 'b: 'a, T: ?Sized + ?Leak + Unsize<U>, U: ?Sized + ?Leak> CoerceUnsized<&'a U> for &'b T {}
+// Omit `T: ?Leak` and `U: ?Leak`.
+impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'b mut T {}
 
 #[lang = "dispatch_from_dyn"]
-trait DispatchFromDyn<T: ?Leak> {}
+trait DispatchFromDyn<T: ?Leak>: ?Leak {}
 impl<'a, T: ?Sized + ?Leak + Unsize<U>, U: ?Sized + ?Leak> DispatchFromDyn<&'a U> for &'a T {}
+// Omit `T: ?Leak` and `U: ?Leak`.
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {}
 
 #[lang = "default_trait1"]
 auto trait Leak {}
@@ -47,25 +52,52 @@ struct NonLeakS;
 impl !Leak for NonLeakS {}
 struct LeakS;
 
-trait Trait {
-    fn leak_foo(&self) {}
-    fn maybe_leak_foo(&self) where Self: ?Leak {}
+fn bounds_check() {
+    trait LeakTr {}
+
+    trait MaybeLeakTr: ?Leak {}
+
+    impl MaybeLeakTr for NonLeakS {}
+
+    impl LeakTr for LeakS {}
+    impl MaybeLeakTr for LeakS {}
+
+    let _: &dyn LeakTr = &NonLeakS;
+    //~^ ERROR  the trait bound `NonLeakS: bounds_check::LeakTr` is not satisfied
+    let _: &dyn LeakTr = &LeakS;
+
+    let _: &(dyn LeakTr + ?Leak) = &NonLeakS;
+    let _: &(dyn LeakTr + ?Leak) = &LeakS;
+
+    let _: &dyn MaybeLeakTr = &NonLeakS;
+    let _: &dyn MaybeLeakTr = &LeakS;
 }
 
-impl Trait for NonLeakS {}
-impl Trait for LeakS {}
-
-fn main() {
-    let _: &dyn Trait = &NonLeakS;
-    //~^ ERROR the trait bound `NonLeakS: Leak` is not satisfied
-    let _: &dyn Trait = &LeakS;
-    let _: &(dyn Trait + ?Leak) = &LeakS;
-    let x: &(dyn Trait + ?Leak) = &NonLeakS;
-    x.leak_foo();
-    //~^ ERROR the trait bound `dyn Trait: Leak` is not satisfied
-    x.maybe_leak_foo();
+fn dyn_compat_check() {
+    trait DynCompatCheck1: ?Leak {
+        fn foo(&self) {}
+    }
+
+    trait DynCompatCheck2: ?Leak {
+        fn mut_foo(&mut self) {}
+    }
+
+    impl DynCompatCheck1 for NonLeakS {}
+    impl DynCompatCheck2 for NonLeakS {}
+
+    let _: &(dyn DynCompatCheck1 + ?Leak) = &NonLeakS;
+    // There is no `?Leak` bound on corresponding `DispatchFromDyn` impl.
+    let _: &dyn DynCompatCheck2 = &NonLeakS;
+    //~^ ERROR the trait `DynCompatCheck2` is not dyn compatible
+}
+
+fn args_check() {
+    trait LeakTr {}
+
     // Ensure that we validate the generic args of relaxed bounds in trait object types.
-    let _: dyn Trait + ?Leak<(), Undefined = ()>;
+    let _: dyn LeakTr + ?Leak<(), Undefined = ()>;
     //~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied
     //~| ERROR associated type `Undefined` not found for `Leak`
 }
+
+fn main() {}
diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr
index b19c082a1b8..b96a2915c33 100644
--- a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr
+++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr
@@ -1,49 +1,57 @@
-error[E0277]: the trait bound `NonLeakS: Leak` is not satisfied
-  --> $DIR/maybe-bounds-in-dyn-traits.rs:59:25
+error[E0277]: the trait bound `NonLeakS: bounds_check::LeakTr` is not satisfied
+  --> $DIR/maybe-bounds-in-dyn-traits.rs:65:26
    |
-LL |     let _: &dyn Trait = &NonLeakS;
-   |                         ^^^^^^^^^ unsatisfied trait bound
+LL |     let _: &dyn LeakTr = &NonLeakS;
+   |                          ^^^^^^^^^ unsatisfied trait bound
    |
-help: the trait `Leak` is not implemented for `NonLeakS`
-  --> $DIR/maybe-bounds-in-dyn-traits.rs:46:1
+help: the trait `bounds_check::LeakTr` is not implemented for `NonLeakS`
+  --> $DIR/maybe-bounds-in-dyn-traits.rs:51:1
    |
 LL | struct NonLeakS;
    | ^^^^^^^^^^^^^^^
-   = note: required for the cast from `&NonLeakS` to `&dyn Trait + Leak`
+   = help: the trait `bounds_check::LeakTr` is implemented for `LeakS`
+   = note: required for the cast from `&NonLeakS` to `&dyn bounds_check::LeakTr + Leak`
 
-error[E0277]: the trait bound `dyn Trait: Leak` is not satisfied
-  --> $DIR/maybe-bounds-in-dyn-traits.rs:64:7
-   |
-LL |     x.leak_foo();
-   |       ^^^^^^^^ the trait `Leak` is not implemented for `dyn Trait`
-   |
-note: required by a bound in `Trait::leak_foo`
-  --> $DIR/maybe-bounds-in-dyn-traits.rs:51:5
-   |
-LL |     fn leak_foo(&self) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait::leak_foo`
+error[E0038]: the trait `DynCompatCheck2` is not dyn compatible
+  --> $DIR/maybe-bounds-in-dyn-traits.rs:90:17
+   |
+LL |         fn mut_foo(&mut self) {}
+   |                    --------- help: consider changing method `mut_foo`'s `self` parameter to be `&self`: `&Self`
+...
+LL |     let _: &dyn DynCompatCheck2 = &NonLeakS;
+   |                 ^^^^^^^^^^^^^^^ `DynCompatCheck2` is not dyn compatible
+   |
+note: for a trait to be dyn compatible it needs to allow building a vtable
+      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
+  --> $DIR/maybe-bounds-in-dyn-traits.rs:82:20
+   |
+LL |     trait DynCompatCheck2: ?Leak {
+   |           --------------- this trait is not dyn compatible...
+LL |         fn mut_foo(&mut self) {}
+   |                    ^^^^^^^^^ ...because method `mut_foo`'s `self` parameter cannot be dispatched on
+   = help: only type `NonLeakS` implements `DynCompatCheck2`; consider using it directly instead.
 
 error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
-  --> $DIR/maybe-bounds-in-dyn-traits.rs:68:25
+  --> $DIR/maybe-bounds-in-dyn-traits.rs:98:26
    |
-LL |     let _: dyn Trait + ?Leak<(), Undefined = ()>;
-   |                         ^^^^-------------------- help: remove the unnecessary generics
-   |                         |
-   |                         expected 0 generic arguments
+LL |     let _: dyn LeakTr + ?Leak<(), Undefined = ()>;
+   |                          ^^^^-------------------- help: remove the unnecessary generics
+   |                          |
+   |                          expected 0 generic arguments
    |
 note: trait defined here, with 0 generic parameters
-  --> $DIR/maybe-bounds-in-dyn-traits.rs:44:12
+  --> $DIR/maybe-bounds-in-dyn-traits.rs:49:12
    |
 LL | auto trait Leak {}
    |            ^^^^
 
 error[E0220]: associated type `Undefined` not found for `Leak`
-  --> $DIR/maybe-bounds-in-dyn-traits.rs:68:34
+  --> $DIR/maybe-bounds-in-dyn-traits.rs:98:35
    |
-LL |     let _: dyn Trait + ?Leak<(), Undefined = ()>;
-   |                                  ^^^^^^^^^ associated type `Undefined` not found
+LL |     let _: dyn LeakTr + ?Leak<(), Undefined = ()>;
+   |                                   ^^^^^^^^^ associated type `Undefined` not found
 
 error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0107, E0220, E0277.
-For more information about an error, try `rustc --explain E0107`.
+Some errors have detailed explanations: E0038, E0107, E0220, E0277.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs
index b3801baaf70..ac4c4aca2ef 100644
--- a/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs
+++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.rs
@@ -14,18 +14,22 @@
 #![no_std]
 #![no_core]
 
+#[lang = "copy"]
+pub trait Copy: ?Leak {}
+
 #[lang = "pointee_sized"]
-trait PointeeSized {}
+trait PointeeSized: ?Leak {}
 
 #[lang = "meta_sized"]
-trait MetaSized: PointeeSized {}
+trait MetaSized: PointeeSized + ?Leak {}
 
 #[lang = "sized"]
-trait Sized: MetaSized {}
+trait Sized: MetaSized + ?Leak {}
 
 #[lang = "legacy_receiver"]
-trait LegacyReceiver {}
+trait LegacyReceiver: ?Leak {}
 impl<T: ?Sized + ?Leak> LegacyReceiver for &T {}
+// Omit `T: ?Leak`.
 impl<T: ?Sized> LegacyReceiver for &mut T {}
 
 #[lang = "default_trait1"]
@@ -38,83 +42,40 @@ struct LeakS;
 mod supertraits {
     use crate::*;
 
-    trait MaybeLeakT1: ?Leak {}
-    trait MaybeLeakT2 where Self: ?Leak {}
+    trait MaybeLeak: ?Leak {}
+    impl MaybeLeak for NonLeakS {}
 
-    impl MaybeLeakT1 for NonLeakS {}
-    impl MaybeLeakT2 for NonLeakS {}
+    trait LeakT {}
+    impl LeakT for NonLeakS {}
+    //~^ ERROR the trait bound `NonLeakS: Leak` is not satisfied
 }
 
-mod maybe_self_assoc_type {
+mod assoc_type_maybe_bounds {
     use crate::*;
 
-    trait TestBase1<T: ?Sized> {}
-    trait TestBase2<T: ?Leak + ?Sized> {}
-
-    trait Test1<T> {
-        type MaybeLeakSelf: TestBase1<Self> where Self: ?Leak;
-        //~^ ERROR the trait bound `Self: Leak` is not satisfied
-        type LeakSelf: TestBase1<Self>;
-    }
-
-    trait Test2<T> {
-        type MaybeLeakSelf: TestBase2<Self> where Self: ?Leak;
-        type LeakSelf: TestBase2<Self>;
-    }
-
-    trait Test3 {
+    trait Test1 {
         type Leak1 = LeakS;
         type Leak2 = NonLeakS;
         //~^ ERROR the trait bound `NonLeakS: Leak` is not satisfied
     }
 
-    trait Test4 {
+    trait Test2 {
         type MaybeLeak1: ?Leak = LeakS;
         type MaybeLeak2: ?Leak = NonLeakS;
     }
-
-    trait Test5: ?Leak {
-        // ok, because assoc types have implicit where Self: Leak
-        type MaybeLeakSelf1: TestBase1<Self>;
-        type MaybeLeakSelf2: TestBase2<Self>;
-    }
-}
-
-mod maybe_self_assoc_const {
-    use crate::*;
-
-    const fn size_of<T: ?Sized>() -> usize {
-        0
-    }
-
-    trait Trait {
-        const CLeak: usize = size_of::<Self>();
-        const CNonLeak: usize = size_of::<Self>() where Self: ?Leak;
-        //~^ ERROR the trait bound `Self: Leak` is not satisfied
-    }
 }
 
 mod methods {
     use crate::*;
 
-    trait Trait {
-        fn leak_foo(&self) {}
-        fn maybe_leak_foo(&self) where Self: ?Leak {}
-        fn mut_leak_foo(&mut self) {}
-        // there is no relax bound on corresponding Receiver impl
-        fn mut_maybe_leak_foo(&mut self) where Self: ?Leak {}
-        //~^ ERROR `&mut Self` cannot be used as the type of `self` without the `arbitrary_self_types`
+    trait ReceiveCheck1: ?Leak {
+        fn foo(&self) {}
     }
 
-    impl Trait for NonLeakS {}
-    impl Trait for LeakS {}
-
-    fn foo() {
-        LeakS.leak_foo();
-        LeakS.maybe_leak_foo();
-        NonLeakS.leak_foo();
-        //~^ ERROR the trait bound `NonLeakS: Leak` is not satisfied
-        NonLeakS.maybe_leak_foo();
+    trait ReceiveCheck2: ?Leak {
+        // There is no `?Leak` bound on corresponding `LegacyReceiver` impl.
+        fn mut_foo(&mut self) {}
+        //~^ ERROR `&mut Self` cannot be used as the type of `self` without the `arbitrary_self_types`
     }
 }
 
diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr
index 372bf817600..ab62ab81b21 100644
--- a/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr
+++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-traits.stderr
@@ -1,81 +1,49 @@
 error[E0277]: the trait bound `NonLeakS: Leak` is not satisfied
-  --> $DIR/maybe-bounds-in-traits.rs:67:22
+  --> $DIR/maybe-bounds-in-traits.rs:49:20
    |
-LL |         type Leak2 = NonLeakS;
-   |                      ^^^^^^^^ unsatisfied trait bound
+LL |     impl LeakT for NonLeakS {}
+   |                    ^^^^^^^^ unsatisfied trait bound
    |
 help: the trait `Leak` is not implemented for `NonLeakS`
-  --> $DIR/maybe-bounds-in-traits.rs:34:1
+  --> $DIR/maybe-bounds-in-traits.rs:38:1
    |
 LL | struct NonLeakS;
    | ^^^^^^^^^^^^^^^
-note: required by a bound in `Test3::Leak2`
-  --> $DIR/maybe-bounds-in-traits.rs:67:9
+note: required by a bound in `LeakT`
+  --> $DIR/maybe-bounds-in-traits.rs:48:5
    |
-LL |         type Leak2 = NonLeakS;
-   |         ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Test3::Leak2`
+LL |     trait LeakT {}
+   |     ^^^^^^^^^^^^^^ required by this bound in `LeakT`
 
-error[E0277]: the trait bound `Self: Leak` is not satisfied
-  --> $DIR/maybe-bounds-in-traits.rs:55:29
+error[E0277]: the trait bound `NonLeakS: Leak` is not satisfied
+  --> $DIR/maybe-bounds-in-traits.rs:58:22
    |
-LL |         type MaybeLeakSelf: TestBase1<Self> where Self: ?Leak;
-   |                             ^^^^^^^^^^^^^^^ the trait `Leak` is not implemented for `Self`
+LL |         type Leak2 = NonLeakS;
+   |                      ^^^^^^^^ unsatisfied trait bound
    |
-note: required by a bound in `TestBase1`
-  --> $DIR/maybe-bounds-in-traits.rs:51:21
+help: the trait `Leak` is not implemented for `NonLeakS`
+  --> $DIR/maybe-bounds-in-traits.rs:38:1
    |
-LL |     trait TestBase1<T: ?Sized> {}
-   |                     ^ required by this bound in `TestBase1`
-help: consider further restricting `Self`
+LL | struct NonLeakS;
+   | ^^^^^^^^^^^^^^^
+note: required by a bound in `Test1::Leak2`
+  --> $DIR/maybe-bounds-in-traits.rs:58:9
    |
-LL |     trait Test1<T>: Leak {
-   |                   ++++++
+LL |         type Leak2 = NonLeakS;
+   |         ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Test1::Leak2`
 
 error[E0658]: `&mut Self` cannot be used as the type of `self` without the `arbitrary_self_types` feature
-  --> $DIR/maybe-bounds-in-traits.rs:105:31
+  --> $DIR/maybe-bounds-in-traits.rs:77:20
    |
-LL |         fn mut_maybe_leak_foo(&mut self) where Self: ?Leak {}
-   |                               ^^^^^^^^^
+LL |         fn mut_foo(&mut self) {}
+   |                    ^^^^^^^^^
    |
    = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
    = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
    = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
-error[E0277]: the trait bound `Self: Leak` is not satisfied
-  --> $DIR/maybe-bounds-in-traits.rs:92:43
-   |
-LL |         const CNonLeak: usize = size_of::<Self>() where Self: ?Leak;
-   |                                           ^^^^ the trait `Leak` is not implemented for `Self`
-   |
-note: required by a bound in `size_of`
-  --> $DIR/maybe-bounds-in-traits.rs:86:22
-   |
-LL |     const fn size_of<T: ?Sized>() -> usize {
-   |                      ^ required by this bound in `size_of`
-help: consider further restricting `Self`
-   |
-LL |     trait Trait: Leak {
-   |                ++++++
-
-error[E0277]: the trait bound `NonLeakS: Leak` is not satisfied
-  --> $DIR/maybe-bounds-in-traits.rs:115:18
-   |
-LL |         NonLeakS.leak_foo();
-   |                  ^^^^^^^^ unsatisfied trait bound
-   |
-help: the trait `Leak` is not implemented for `NonLeakS`
-  --> $DIR/maybe-bounds-in-traits.rs:34:1
-   |
-LL | struct NonLeakS;
-   | ^^^^^^^^^^^^^^^
-note: required by a bound in `methods::Trait::leak_foo`
-  --> $DIR/maybe-bounds-in-traits.rs:101:9
-   |
-LL |         fn leak_foo(&self) {}
-   |         ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait::leak_foo`
-
-error: aborting due to 5 previous errors
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0277, E0658.
 For more information about an error, try `rustc --explain E0277`.