about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-06-05 11:32:18 +0000
committerbors <bors@rust-lang.org>2024-06-05 11:32:18 +0000
commitdb8aca48129d86b2623e3ac8cbcf2902d4d313ad (patch)
tree637294c8b1a43817f408a70a5da24d9b64d672a4
parent5ee2dfd2bcbb66a69a46aaa342204e0dfdb70516 (diff)
parentf12fe3a33e5e94f1f49cd6d4a785d1cf7a0a02b9 (diff)
downloadrust-db8aca48129d86b2623e3ac8cbcf2902d4d313ad.tar.gz
rust-db8aca48129d86b2623e3ac8cbcf2902d4d313ad.zip
Auto merge of #126016 - workingjubilee:rollup-nh6ehbz, r=workingjubilee
Rollup of 12 pull requests

Successful merges:

 - #123168 (Add `size_of` and `size_of_val` and `align_of` and `align_of_val` to the prelude)
 - #125273 (bootstrap: implement new feature `bootstrap-self-test`)
 - #125683 (Rewrite `suspicious-library`, `resolve-rename` and `incr-prev-body-beyond-eof` `run-make` tests in `rmake.rs` format)
 - #125815 (`rustc_parse` top-level cleanups)
 - #125903 (rustc_span: Inline some hot functions)
 - #125906 (Remove a bunch of redundant args from `report_method_error`)
 - #125920 (Allow static mut definitions with #[linkage])
 - #125982 (Make deleting on LinkedList aware of the allocator)
 - #125995 (Use inline const blocks to create arrays of `MaybeUninit`.)
 - #125996 (Closures are recursively reachable)
 - #126003 (Add a co-maintainer for the two ARMv4T targets)
 - #126004 (Add another test for hidden types capturing lifetimes that outlive but arent mentioned in substs)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_builtin_macros/src/cfg_eval.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/cmdline_attrs.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/source_util.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs25
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs10
-rw-r--r--compiler/rustc_expand/src/base.rs6
-rw-r--r--compiler/rustc_expand/src/module.rs5
-rw-r--r--compiler/rustc_expand/src/proc_macro.rs5
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs18
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs39
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/method/mod.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs58
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs8
-rw-r--r--compiler/rustc_interface/src/interface.rs6
-rw-r--r--compiler/rustc_interface/src/passes.rs17
-rw-r--r--compiler/rustc_middle/src/query/erase.rs2
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs4
-rw-r--r--compiler/rustc_parse/src/lexer/tokentrees.rs50
-rw-r--r--compiler/rustc_parse/src/lexer/unicode_chars.rs75
-rw-r--r--compiler/rustc_parse/src/lib.rs158
-rw-r--r--compiler/rustc_parse/src/parser/attr.rs2
-rw-r--r--compiler/rustc_parse/src/parser/tests.rs22
-rw-r--r--compiler/rustc_passes/src/reachable.rs1
-rw-r--r--compiler/rustc_span/src/span_encoding.rs1
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--library/alloc/src/collections/linked_list.rs4
-rw-r--r--library/alloc/src/collections/linked_list/tests.rs39
-rw-r--r--library/alloc/src/rc.rs2
-rw-r--r--library/alloc/src/sync.rs2
-rw-r--r--library/core/src/cell.rs2
-rw-r--r--library/core/src/intrinsics.rs1
-rw-r--r--library/core/src/mem/maybe_uninit.rs17
-rw-r--r--library/core/src/prelude/common.rs3
-rw-r--r--library/core/src/ptr/mod.rs2
-rw-r--r--library/core/src/slice/raw.rs1
-rw-r--r--library/core/src/sync/atomic.rs3
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs2
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs2
-rw-r--r--library/proc_macro/src/bridge/fxhash.rs1
-rw-r--r--library/std/src/io/error/repr_bitpacked.rs1
-rw-r--r--library/std/src/os/unix/net/ancillary.rs2
-rw-r--r--library/std/src/prelude/common.rs3
-rw-r--r--library/std/src/prelude/mod.rs4
-rw-r--r--src/bootstrap/Cargo.toml1
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs1
-rw-r--r--src/bootstrap/src/core/config/config.rs19
-rw-r--r--src/bootstrap/src/core/config/tests.rs28
-rw-r--r--src/bootstrap/src/core/download.rs22
-rw-r--r--src/bootstrap/src/core/sanity.rs16
-rw-r--r--src/doc/rustc/src/platform-support/armv4t-none-eabi.md1
-rw-r--r--src/librustdoc/clean/render_macro_matchers.rs2
-rw-r--r--src/librustdoc/doctest.rs23
-rw-r--r--src/librustdoc/passes/lint/check_code_block_syntax.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs4
-rw-r--r--src/tools/compiletest/src/header.rs1
-rw-r--r--src/tools/run-make-support/src/rustc.rs6
-rw-r--r--src/tools/rustfmt/src/parse/macros/mod.rs4
-rw-r--r--src/tools/rustfmt/src/parse/parser.rs27
-rw-r--r--src/tools/tidy/src/allowed_run_make_makefiles.txt3
-rw-r--r--tests/run-make/incr-prev-body-beyond-eof/Makefile19
-rw-r--r--tests/run-make/incr-prev-body-beyond-eof/rmake.rs27
-rw-r--r--tests/run-make/resolve-rename/Makefile7
-rw-r--r--tests/run-make/resolve-rename/rmake.rs16
-rw-r--r--tests/run-make/suspicious-library/Makefile8
-rw-r--r--tests/run-make/suspicious-library/rmake.rs14
-rw-r--r--tests/ui-fulldeps/mod_dir_path_canonicalized.rs4
-rw-r--r--tests/ui-fulldeps/pprust-expr-roundtrip.rs7
-rw-r--r--tests/ui/cross-crate/auxiliary/static_init_aux.rs6
-rw-r--r--tests/ui/cross-crate/static-init.rs2
-rw-r--r--tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.rs38
-rw-r--r--tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.stderr15
-rw-r--r--tests/ui/issues/issue-28344.stderr2
-rw-r--r--tests/ui/linkage-attr/linkage-attr-mutable-static.rs15
-rw-r--r--tests/ui/linkage-attr/linkage-attr-mutable-static.stderr10
-rw-r--r--tests/ui/resolve/filter-intrinsics.rs4
-rw-r--r--tests/ui/resolve/filter-intrinsics.stderr8
-rw-r--r--tests/ui/resolve/issue-82865.stderr7
-rw-r--r--tests/ui/traits/item-privacy.stderr9
79 files changed, 557 insertions, 453 deletions
diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs
index 5f63a8ae0a8..03aff6f9633 100644
--- a/compiler/rustc_builtin_macros/src/cfg_eval.rs
+++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs
@@ -196,7 +196,7 @@ impl CfgEval<'_, '_> {
         // Re-parse the tokens, setting the `capture_cfg` flag to save extra information
         // to the captured `AttrTokenStream` (specifically, we capture
         // `AttrTokenTree::AttributesData` for all occurrences of `#[cfg]` and `#[cfg_attr]`)
-        let mut parser = rustc_parse::stream_to_parser(&self.cfg.sess.psess, orig_tokens, None);
+        let mut parser = Parser::new(&self.cfg.sess.psess, orig_tokens, None);
         parser.capture_cfg = true;
         match parse_annotatable_with(&mut parser) {
             Ok(a) => annotatable = a,
diff --git a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs
index ada82e45712..e9b63b4abeb 100644
--- a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs
+++ b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs
@@ -4,16 +4,17 @@ use crate::errors;
 use rustc_ast::attr::mk_attr;
 use rustc_ast::token;
 use rustc_ast::{self as ast, AttrItem, AttrStyle};
+use rustc_parse::{new_parser_from_source_str, unwrap_or_emit_fatal};
 use rustc_session::parse::ParseSess;
 use rustc_span::FileName;
 
 pub fn inject(krate: &mut ast::Crate, psess: &ParseSess, attrs: &[String]) {
     for raw_attr in attrs {
-        let mut parser = rustc_parse::new_parser_from_source_str(
+        let mut parser = unwrap_or_emit_fatal(new_parser_from_source_str(
             psess,
             FileName::cli_crate_attr_source_code(raw_attr),
             raw_attr.clone(),
-        );
+        ));
 
         let start_span = parser.token.span;
         let AttrItem { path, args, tokens: _ } = match parser.parse_attr_item(false) {
diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs
index 29e991525a9..dc1d82df0c3 100644
--- a/compiler/rustc_builtin_macros/src/source_util.rs
+++ b/compiler/rustc_builtin_macros/src/source_util.rs
@@ -12,8 +12,8 @@ use rustc_expand::base::{
 };
 use rustc_expand::module::DirOwnership;
 use rustc_lint_defs::BuiltinLintDiag;
-use rustc_parse::new_parser_from_file;
 use rustc_parse::parser::{ForceCollect, Parser};
+use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal};
 use rustc_session::lint::builtin::INCOMPLETE_INCLUDE;
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::Symbol;
@@ -126,7 +126,7 @@ pub(crate) fn expand_include<'cx>(
             return ExpandResult::Ready(DummyResult::any(sp, guar));
         }
     };
-    let p = new_parser_from_file(cx.psess(), &file, Some(sp));
+    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`.
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 5d7257b15c4..15955170e87 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -324,21 +324,22 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
                     let linkage = Some(linkage_by_name(tcx, did, val.as_str()));
                     if tcx.is_foreign_item(did) {
                         codegen_fn_attrs.import_linkage = linkage;
+
+                        if tcx.is_mutable_static(did.into()) {
+                            let mut diag = tcx.dcx().struct_span_err(
+                                attr.span,
+                                "extern mutable statics are not allowed with `#[linkage]`",
+                            );
+                            diag.note(
+                                "marking the extern static mutable would allow changing which symbol \
+                                 the static references rather than make the target of the symbol \
+                                 mutable",
+                            );
+                            diag.emit();
+                        }
                     } else {
                         codegen_fn_attrs.linkage = linkage;
                     }
-                    if tcx.is_mutable_static(did.into()) {
-                        let mut diag = tcx.dcx().struct_span_err(
-                            attr.span,
-                            "mutable statics are not allowed with `#[linkage]`",
-                        );
-                        diag.note(
-                            "making the static mutable would allow changing which symbol the \
-                             static references rather than make the target of the symbol \
-                             mutable",
-                        );
-                        diag.emit();
-                    }
                 }
             }
             sym::link_section => {
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 627fd74c8d7..93a65290602 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -32,6 +32,7 @@ use rustc_interface::{interface, Queries};
 use rustc_lint::unerased_lint_store;
 use rustc_metadata::creader::MetadataLoader;
 use rustc_metadata::locator;
+use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
 use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS};
 use rustc_session::config::{ErrorOutputType, Input, OutFileName, OutputType};
 use rustc_session::getopts::{self, Matches};
@@ -1264,12 +1265,13 @@ pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option<geto
 }
 
 fn parse_crate_attrs<'a>(sess: &'a Session) -> PResult<'a, ast::AttrVec> {
-    match &sess.io.input {
-        Input::File(ifile) => rustc_parse::parse_crate_attrs_from_file(ifile, &sess.psess),
+    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 } => {
-            rustc_parse::parse_crate_attrs_from_source_str(name.clone(), input.clone(), &sess.psess)
+            new_parser_from_source_str(&sess.psess, name.clone(), input.clone())
         }
-    }
+    });
+    parser.parse_inner_attributes()
 }
 
 /// Runs a closure and catches unwinds triggered by fatal errors.
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 4539129bd0f..b3f6a35f3a4 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -15,7 +15,7 @@ use rustc_data_structures::sync::{self, Lrc};
 use rustc_errors::{DiagCtxt, ErrorGuaranteed, PResult};
 use rustc_feature::Features;
 use rustc_lint_defs::{BufferedEarlyLint, RegisteredTools};
-use rustc_parse::{parser, MACRO_ARGUMENTS};
+use rustc_parse::{parser::Parser, MACRO_ARGUMENTS};
 use rustc_session::config::CollapseMacroDebuginfo;
 use rustc_session::{parse::ParseSess, Limit, Session};
 use rustc_span::def_id::{CrateNum, DefId, LocalDefId};
@@ -1149,8 +1149,8 @@ impl<'a> ExtCtxt<'a> {
     pub fn monotonic_expander<'b>(&'b mut self) -> expand::MacroExpander<'b, 'a> {
         expand::MacroExpander::new(self, true)
     }
-    pub fn new_parser_from_tts(&self, stream: TokenStream) -> parser::Parser<'a> {
-        rustc_parse::stream_to_parser(&self.sess.psess, stream, MACRO_ARGUMENTS)
+    pub fn new_parser_from_tts(&self, stream: TokenStream) -> Parser<'a> {
+        Parser::new(&self.sess.psess, stream, MACRO_ARGUMENTS)
     }
     pub fn source_map(&self) -> &'a SourceMap {
         self.sess.psess.source_map()
diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs
index c8983619e70..506bd445be3 100644
--- a/compiler/rustc_expand/src/module.rs
+++ b/compiler/rustc_expand/src/module.rs
@@ -5,8 +5,8 @@ use crate::errors::{
 use rustc_ast::ptr::P;
 use rustc_ast::{token, AttrVec, Attribute, Inline, Item, ModSpans};
 use rustc_errors::{Diag, ErrorGuaranteed};
-use rustc_parse::new_parser_from_file;
 use rustc_parse::validate_attr;
+use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal};
 use rustc_session::parse::ParseSess;
 use rustc_session::Session;
 use rustc_span::symbol::{sym, Ident};
@@ -66,7 +66,8 @@ pub(crate) fn parse_external_mod(
         }
 
         // Actually parse the external file as a module.
-        let mut parser = 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, Some(span)));
         let (inner_attrs, items, inner_span) =
             parser.parse_mod(&token::Eof).map_err(|err| ModError::ParserError(err))?;
         attrs.extend(inner_attrs);
diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs
index c11369f505f..96145affe0a 100644
--- a/compiler/rustc_expand/src/proc_macro.rs
+++ b/compiler/rustc_expand/src/proc_macro.rs
@@ -6,7 +6,7 @@ use rustc_ast as ast;
 use rustc_ast::ptr::P;
 use rustc_ast::tokenstream::TokenStream;
 use rustc_errors::ErrorGuaranteed;
-use rustc_parse::parser::ForceCollect;
+use rustc_parse::parser::{ForceCollect, Parser};
 use rustc_session::config::ProcMacroExecutionStrategy;
 use rustc_span::profiling::SpannedEventArgRecorder;
 use rustc_span::Span;
@@ -154,8 +154,7 @@ impl MultiItemModifier for DeriveProcMacro {
         };
 
         let error_count_before = ecx.dcx().err_count();
-        let mut parser =
-            rustc_parse::stream_to_parser(&ecx.sess.psess, stream, Some("proc-macro derive"));
+        let mut parser = Parser::new(&ecx.sess.psess, stream, Some("proc-macro derive"));
         let mut items = vec![];
 
         loop {
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index c2e799abae8..93f8682090d 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -13,7 +13,8 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{Diag, ErrorGuaranteed, MultiSpan, PResult};
 use rustc_parse::lexer::nfc_normalize;
-use rustc_parse::parse_stream_from_source_str;
+use rustc_parse::parser::Parser;
+use rustc_parse::{new_parser_from_source_str, source_str_to_stream, unwrap_or_emit_fatal};
 use rustc_session::parse::ParseSess;
 use rustc_span::def_id::CrateNum;
 use rustc_span::symbol::{self, sym, Symbol};
@@ -466,7 +467,8 @@ 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 = rustc_parse::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()));
 
         let first_span = parser.token.span.data();
         let minus_present = parser.eat(&token::BinOp(token::Minus));
@@ -538,12 +540,12 @@ impl server::TokenStream for Rustc<'_, '_> {
     }
 
     fn from_str(&mut self, src: &str) -> Self::TokenStream {
-        parse_stream_from_source_str(
+        unwrap_or_emit_fatal(source_str_to_stream(
+            self.psess(),
             FileName::proc_macro_source_code(src),
             src.to_string(),
-            self.psess(),
             Some(self.call_site),
-        )
+        ))
     }
 
     fn to_string(&mut self, stream: &Self::TokenStream) -> String {
@@ -553,11 +555,7 @@ impl server::TokenStream for Rustc<'_, '_> {
     fn expand_expr(&mut self, stream: &Self::TokenStream) -> Result<Self::TokenStream, ()> {
         // Parse the expression from our tokenstream.
         let expr: PResult<'_, _> = try {
-            let mut p = rustc_parse::stream_to_parser(
-                self.psess(),
-                stream.clone(),
-                Some("proc_macro expand expr"),
-            );
+            let mut p = Parser::new(self.psess(), stream.clone(), Some("proc_macro expand expr"));
             let expr = p.parse_expr()?;
             if p.token != token::Eof {
                 p.unexpected()?;
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 3d88c425524..4cc936eed08 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -13,7 +13,6 @@ use crate::errors::{
     YieldExprOutsideOfCoroutine,
 };
 use crate::fatally_break_rust;
-use crate::method::SelfSource;
 use crate::type_error_struct;
 use crate::CoroutineTypes;
 use crate::Expectation::{self, ExpectCastableToType, ExpectHasType, NoExpectation};
@@ -223,7 +222,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let ty = ensure_sufficient_stack(|| match &expr.kind {
             hir::ExprKind::Path(
                 qpath @ (hir::QPath::Resolved(..) | hir::QPath::TypeRelative(..)),
-            ) => self.check_expr_path(qpath, expr, args, call),
+            ) => self.check_expr_path(qpath, expr, Some(args), call),
             _ => self.check_expr_kind(expr, expected),
         });
         let ty = self.resolve_vars_if_possible(ty);
@@ -290,7 +289,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ExprKind::Path(QPath::LangItem(lang_item, _)) => {
                 self.check_lang_item_path(lang_item, expr)
             }
-            ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr, &[], None),
+            ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr, None, None),
             ExprKind::InlineAsm(asm) => {
                 // We defer some asm checks as we may not have resolved the input and output types yet (they may still be infer vars).
                 self.deferred_asm_checks.borrow_mut().push((asm, expr.hir_id));
@@ -502,12 +501,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         qpath: &'tcx hir::QPath<'tcx>,
         expr: &'tcx hir::Expr<'tcx>,
-        args: &'tcx [hir::Expr<'tcx>],
+        args: Option<&'tcx [hir::Expr<'tcx>]>,
         call: Option<&'tcx hir::Expr<'tcx>>,
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
         let (res, opt_ty, segs) =
-            self.resolve_ty_and_res_fully_qualified_call(qpath, expr.hir_id, expr.span, Some(args));
+            self.resolve_ty_and_res_fully_qualified_call(qpath, expr.hir_id, expr.span);
         let ty = match res {
             Res::Err => {
                 self.suggest_assoc_method_call(segs);
@@ -564,7 +563,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // We just want to check sizedness, so instead of introducing
                     // placeholder lifetimes with probing, we just replace higher lifetimes
                     // with fresh vars.
-                    let span = args.get(i).map(|a| a.span).unwrap_or(expr.span);
+                    let span = args.and_then(|args| args.get(i)).map_or(expr.span, |arg| arg.span);
                     let input = self.instantiate_binder_with_fresh_vars(
                         span,
                         infer::BoundRegionConversionTime::FnCall,
@@ -1331,9 +1330,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let rcvr_t = self.check_expr(rcvr);
         // no need to check for bot/err -- callee does that
         let rcvr_t = self.structurally_resolve_type(rcvr.span, rcvr_t);
-        let span = segment.ident.span;
 
-        let method = match self.lookup_method(rcvr_t, segment, span, expr, rcvr, args) {
+        let method = match self.lookup_method(rcvr_t, segment, segment.ident.span, expr, rcvr, args)
+        {
             Ok(method) => {
                 // We could add a "consider `foo::<params>`" suggestion here, but I wasn't able to
                 // trigger this codepath causing `structurally_resolve_type` to emit an error.
@@ -1342,18 +1341,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             Err(error) => {
                 if segment.ident.name != kw::Empty {
-                    if let Some(err) = self.report_method_error(
-                        span,
-                        Some(rcvr),
-                        rcvr_t,
-                        segment.ident,
-                        expr.hir_id,
-                        SelfSource::MethodCall(rcvr),
-                        error,
-                        Some(args),
-                        expected,
-                        false,
-                    ) {
+                    if let Some(err) =
+                        self.report_method_error(expr.hir_id, rcvr_t, error, expected, false)
+                    {
                         err.emit();
                     }
                 }
@@ -1362,7 +1352,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
 
         // Call the generic checker.
-        self.check_method_argument_types(span, expr, method, args, DontTupleArguments, expected)
+        self.check_method_argument_types(
+            segment.ident.span,
+            expr,
+            method,
+            args,
+            DontTupleArguments,
+            expected,
+        )
     }
 
     fn check_expr_cast(
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 58eb0c28179..7d7324a2b64 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -1,6 +1,6 @@
 use crate::callee::{self, DeferredCallResolution};
 use crate::errors::{self, CtorIsPrivate};
-use crate::method::{self, MethodCallee, SelfSource};
+use crate::method::{self, MethodCallee};
 use crate::rvalue_scopes;
 use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LoweredTy};
 use rustc_data_structures::fx::FxHashSet;
@@ -735,7 +735,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         qpath: &'tcx QPath<'tcx>,
         hir_id: HirId,
         span: Span,
-        args: Option<&'tcx [hir::Expr<'tcx>]>,
     ) -> (Res, Option<LoweredTy<'tcx>>, &'tcx [hir::PathSegment<'tcx>]) {
         debug!(
             "resolve_ty_and_res_fully_qualified_call: qpath={:?} hir_id={:?} span={:?}",
@@ -828,14 +827,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                 if item_name.name != kw::Empty {
                     if let Some(e) = self.report_method_error(
-                        span,
-                        None,
-                        ty.normalized,
-                        item_name,
                         hir_id,
-                        SelfSource::QPath(qself),
+                        ty.normalized,
                         error,
-                        args,
                         Expectation::NoExpectation,
                         trait_missing_method && span.edition().at_least_rust_2021(), // emits missing method for trait only after edition 2021
                     ) {
diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs
index 4165ccb1b80..1f90d5e4c88 100644
--- a/compiler/rustc_hir_typeck/src/method/mod.rs
+++ b/compiler/rustc_hir_typeck/src/method/mod.rs
@@ -7,7 +7,6 @@ mod prelude_edition_lints;
 pub mod probe;
 mod suggest;
 
-pub use self::suggest::SelfSource;
 pub use self::MethodError::*;
 
 use crate::FnCtxt;
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index daaaf630f2c..b3947e142b2 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -16,11 +16,11 @@ use rustc_data_structures::unord::UnordSet;
 use rustc_errors::{
     codes::*, pluralize, struct_span_code_err, Applicability, Diag, MultiSpan, StashKey,
 };
-use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::PathSegment;
+use rustc_hir::{self as hir, HirId};
 use rustc_hir::{ExprKind, Node, QPath};
 use rustc_infer::infer::{self, RegionVariableOrigin};
 use rustc_middle::bug;
@@ -187,37 +187,56 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     #[instrument(level = "debug", skip(self))]
     pub fn report_method_error(
         &self,
-        span: Span,
-        rcvr_opt: Option<&'tcx hir::Expr<'tcx>>,
+        call_id: HirId,
         rcvr_ty: Ty<'tcx>,
-        item_name: Ident,
-        expr_id: hir::HirId,
-        source: SelfSource<'tcx>,
         error: MethodError<'tcx>,
-        args: Option<&'tcx [hir::Expr<'tcx>]>,
         expected: Expectation<'tcx>,
         trait_missing_method: bool,
     ) -> Option<Diag<'_>> {
+        let (span, sugg_span, source, item_name, args) = match self.tcx.hir_node(call_id) {
+            hir::Node::Expr(&hir::Expr {
+                kind: hir::ExprKind::MethodCall(segment, rcvr, args, _),
+                span,
+                ..
+            }) => {
+                (segment.ident.span, span, SelfSource::MethodCall(rcvr), segment.ident, Some(args))
+            }
+            hir::Node::Expr(&hir::Expr {
+                kind: hir::ExprKind::Path(QPath::TypeRelative(rcvr, segment)),
+                span,
+                ..
+            })
+            | hir::Node::Pat(&hir::Pat {
+                kind:
+                    hir::PatKind::Path(QPath::TypeRelative(rcvr, segment))
+                    | hir::PatKind::Struct(QPath::TypeRelative(rcvr, segment), ..)
+                    | hir::PatKind::TupleStruct(QPath::TypeRelative(rcvr, segment), ..),
+                span,
+                ..
+            }) => {
+                let args = match self.tcx.parent_hir_node(call_id) {
+                    hir::Node::Expr(&hir::Expr {
+                        kind: hir::ExprKind::Call(callee, args), ..
+                    }) if callee.hir_id == call_id => Some(args),
+                    _ => None,
+                };
+                (segment.ident.span, span, SelfSource::QPath(rcvr), segment.ident, args)
+            }
+            node => unreachable!("{node:?}"),
+        };
+
         // Avoid suggestions when we don't know what's going on.
         if rcvr_ty.references_error() {
             return None;
         }
 
-        let sugg_span = if let SelfSource::MethodCall(expr) = source {
-            // Given `foo.bar(baz)`, `expr` is `bar`, but we want to point to the whole thing.
-            self.tcx.hir().expect_expr(self.tcx.parent_hir_id(expr.hir_id)).span
-        } else {
-            span
-        };
-
         match error {
             MethodError::NoMatch(mut no_match_data) => {
                 return self.report_no_match_method_error(
                     span,
-                    rcvr_opt,
                     rcvr_ty,
                     item_name,
-                    expr_id,
+                    call_id,
                     source,
                     args,
                     sugg_span,
@@ -362,7 +381,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     pub fn suggest_use_shadowed_binding_with_method(
         &self,
-        rcvr_opt: Option<&'tcx hir::Expr<'tcx>>,
+        self_source: SelfSource<'tcx>,
         method_name: Ident,
         ty_str_reported: &str,
         err: &mut Diag<'_>,
@@ -502,7 +521,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         }
 
-        if let Some(rcvr) = rcvr_opt
+        if let SelfSource::MethodCall(rcvr) = self_source
             && let hir::ExprKind::Path(QPath::Resolved(_, path)) = rcvr.kind
             && let hir::def::Res::Local(recv_id) = path.res
             && let Some(segment) = path.segments.first()
@@ -548,7 +567,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn report_no_match_method_error(
         &self,
         mut span: Span,
-        rcvr_opt: Option<&'tcx hir::Expr<'tcx>>,
         rcvr_ty: Ty<'tcx>,
         item_name: Ident,
         expr_id: hir::HirId,
@@ -658,7 +676,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             if is_method {
                 self.suggest_use_shadowed_binding_with_method(
-                    rcvr_opt,
+                    source,
                     item_name,
                     &ty_str_reported,
                     &mut err,
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index b37aba38619..93fb83fb3e4 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -223,9 +223,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let PatInfo { binding_mode, max_ref_mutbl, top_info: ti, current_depth, .. } = pat_info;
 
         let path_res = match &pat.kind {
-            PatKind::Path(qpath) => Some(
-                self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span, None),
-            ),
+            PatKind::Path(qpath) => {
+                Some(self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span))
+            }
             _ => None,
         };
         let adjust_mode = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res));
@@ -1184,7 +1184,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Resolve the path and check the definition for errors.
         let (res, opt_ty, segments) =
-            self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span, None);
+            self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span);
         if res == Res::Err {
             let e = tcx.dcx().span_delayed_bug(pat.span, "`Res::Err` but no error emitted");
             self.set_tainted_by_errors(e);
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index 5254a6576f9..c95a10f4e8d 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -14,7 +14,7 @@ use rustc_lint::LintStore;
 use rustc_middle::ty;
 use rustc_middle::ty::CurrentGcx;
 use rustc_middle::util::Providers;
-use rustc_parse::maybe_new_parser_from_source_str;
+use rustc_parse::new_parser_from_source_str;
 use rustc_query_impl::QueryCtxt;
 use rustc_query_system::query::print_query_stack;
 use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName};
@@ -67,7 +67,7 @@ pub(crate) fn parse_cfg(dcx: &DiagCtxt, cfgs: Vec<String>) -> Cfg {
                 };
             }
 
-            match maybe_new_parser_from_source_str(&psess, filename, s.to_string()) {
+            match new_parser_from_source_str(&psess, filename, s.to_string()) {
                 Ok(mut parser) => match parser.parse_meta_item() {
                     Ok(meta_item) if parser.token == token::Eof => {
                         if meta_item.path.segments.len() != 1 {
@@ -166,7 +166,7 @@ pub(crate) fn parse_check_cfg(dcx: &DiagCtxt, specs: Vec<String>) -> CheckCfg {
             error!("expected `cfg(name, values(\"value1\", \"value2\", ... \"valueN\"))`")
         };
 
-        let mut parser = match maybe_new_parser_from_source_str(&psess, filename, s.to_string()) {
+        let mut parser = match new_parser_from_source_str(&psess, filename, s.to_string()) {
             Ok(parser) => parser,
             Err(errs) => {
                 errs.into_iter().for_each(|err| err.cancel());
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index b678582766d..a342577cffb 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -19,7 +19,9 @@ use rustc_middle::arena::Arena;
 use rustc_middle::dep_graph::DepGraph;
 use rustc_middle::ty::{self, GlobalCtxt, RegisteredTools, TyCtxt};
 use rustc_middle::util::Providers;
-use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str, validate_attr};
+use rustc_parse::{
+    new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal, validate_attr,
+};
 use rustc_passes::{abi_test, hir_stats, layout_test};
 use rustc_resolve::Resolver;
 use rustc_session::code_stats::VTableSizeInfo;
@@ -42,11 +44,14 @@ use std::{env, fs, iter};
 use tracing::{info, instrument};
 
 pub fn parse<'a>(sess: &'a Session) -> PResult<'a, ast::Crate> {
-    let krate = sess.time("parse_crate", || match &sess.io.input {
-        Input::File(file) => parse_crate_from_file(file, &sess.psess),
-        Input::Str { input, name } => {
-            parse_crate_from_source_str(name.clone(), input.clone(), &sess.psess)
-        }
+    let 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())
+            }
+        });
+        parser.parse_crate_mod()
     })?;
 
     if sess.opts.unstable_opts.input_stats {
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs
index f98dbf8a0bd..b29a86d58ed 100644
--- a/compiler/rustc_middle/src/query/erase.rs
+++ b/compiler/rustc_middle/src/query/erase.rs
@@ -4,7 +4,7 @@ use crate::traits;
 use crate::ty::adjustment::CoerceUnsizedInfo;
 use crate::ty::{self, Ty};
 use std::intrinsics::transmute_unchecked;
-use std::mem::{size_of, MaybeUninit};
+use std::mem::MaybeUninit;
 
 #[derive(Copy, Clone)]
 pub struct Erased<T: Copy> {
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index d3a6a033978..43f4963b27a 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -42,7 +42,7 @@ pub(crate) struct UnmatchedDelim {
     pub candidate_span: Option<Span>,
 }
 
-pub(crate) fn parse_token_trees<'psess, 'src>(
+pub(crate) fn lex_token_trees<'psess, 'src>(
     psess: &'psess ParseSess,
     mut src: &'src str,
     mut start_pos: BytePos,
@@ -66,7 +66,7 @@ pub(crate) fn parse_token_trees<'psess, 'src>(
         last_lifetime: None,
     };
     let (stream, res, unmatched_delims) =
-        tokentrees::TokenTreesReader::parse_all_token_trees(string_reader);
+        tokentrees::TokenTreesReader::lex_all_token_trees(string_reader);
     match res {
         Ok(()) if unmatched_delims.is_empty() => Ok(stream),
         _ => {
diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs
index eabe0226b2f..f7645446081 100644
--- a/compiler/rustc_parse/src/lexer/tokentrees.rs
+++ b/compiler/rustc_parse/src/lexer/tokentrees.rs
@@ -2,6 +2,7 @@ use super::diagnostics::report_suspicious_mismatch_block;
 use super::diagnostics::same_indentation_level;
 use super::diagnostics::TokenTreeDiagInfo;
 use super::{StringReader, UnmatchedDelim};
+use crate::Parser;
 use rustc_ast::token::{self, Delimiter, Token};
 use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
 use rustc_ast_pretty::pprust::token_to_string;
@@ -17,7 +18,7 @@ pub(super) struct TokenTreesReader<'psess, 'src> {
 }
 
 impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
-    pub(super) fn parse_all_token_trees(
+    pub(super) fn lex_all_token_trees(
         string_reader: StringReader<'psess, 'src>,
     ) -> (TokenStream, Result<(), Vec<PErr<'psess>>>, Vec<UnmatchedDelim>) {
         let mut tt_reader = TokenTreesReader {
@@ -25,14 +26,13 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
             token: Token::dummy(),
             diag_info: TokenTreeDiagInfo::default(),
         };
-        let (_open_spacing, stream, res) =
-            tt_reader.parse_token_trees(/* is_delimited */ false);
+        let (_open_spacing, stream, res) = tt_reader.lex_token_trees(/* is_delimited */ false);
         (stream, res, tt_reader.diag_info.unmatched_delims)
     }
 
-    // Parse a stream of tokens into a list of `TokenTree`s. The `Spacing` in
-    // the result is that of the opening delimiter.
-    fn parse_token_trees(
+    // Lex into a token stream. The `Spacing` in the result is that of the
+    // opening delimiter.
+    fn lex_token_trees(
         &mut self,
         is_delimited: bool,
     ) -> (Spacing, TokenStream, Result<(), Vec<PErr<'psess>>>) {
@@ -42,12 +42,10 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
         let mut buf = Vec::new();
         loop {
             match self.token.kind {
-                token::OpenDelim(delim) => {
-                    buf.push(match self.parse_token_tree_open_delim(delim) {
-                        Ok(val) => val,
-                        Err(errs) => return (open_spacing, TokenStream::new(buf), Err(errs)),
-                    })
-                }
+                token::OpenDelim(delim) => buf.push(match self.lex_token_tree_open_delim(delim) {
+                    Ok(val) => val,
+                    Err(errs) => return (open_spacing, TokenStream::new(buf), Err(errs)),
+                }),
                 token::CloseDelim(delim) => {
                     return (
                         open_spacing,
@@ -95,24 +93,24 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
         err
     }
 
-    fn parse_token_tree_open_delim(
+    fn lex_token_tree_open_delim(
         &mut self,
         open_delim: Delimiter,
     ) -> Result<TokenTree, Vec<PErr<'psess>>> {
-        // The span for beginning of the delimited section
+        // The span for beginning of the delimited section.
         let pre_span = self.token.span;
 
         self.diag_info.open_braces.push((open_delim, self.token.span));
 
-        // Parse the token trees within the delimiters.
+        // Lex the token trees within the delimiters.
         // We stop at any delimiter so we can try to recover if the user
         // uses an incorrect delimiter.
-        let (open_spacing, tts, res) = self.parse_token_trees(/* is_delimited */ true);
+        let (open_spacing, tts, res) = self.lex_token_trees(/* is_delimited */ true);
         if let Err(errs) = res {
             return Err(self.unclosed_delim_err(tts, errs));
         }
 
-        // Expand to cover the entire delimited token tree
+        // Expand to cover the entire delimited token tree.
         let delim_span = DelimSpan::from_pair(pre_span, self.token.span);
         let sm = self.string_reader.psess.source_map();
 
@@ -150,7 +148,7 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
                     self.diag_info.last_unclosed_found_span = Some(self.token.span);
                     // This is a conservative error: only report the last unclosed
                     // delimiter. The previous unclosed delimiters could actually be
-                    // closed! The parser just hasn't gotten to them yet.
+                    // closed! The lexer just hasn't gotten to them yet.
                     if let Some(&(_, sp)) = self.diag_info.open_braces.last() {
                         unclosed_delimiter = Some(sp);
                     };
@@ -234,11 +232,11 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
     ) -> Vec<PErr<'psess>> {
         // If there are unclosed delims, see if there are diff markers and if so, point them
         // out instead of complaining about the unclosed delims.
-        let mut parser = crate::stream_to_parser(self.string_reader.psess, tts, None);
+        let mut parser = Parser::new(self.string_reader.psess, tts, None);
         let mut diff_errs = vec![];
-        // Suggest removing a `{` we think appears in an `if`/`while` condition
-        // We want to suggest removing a `{` only if we think we're in an `if`/`while` condition, but
-        // we have no way of tracking this in the lexer itself, so we piggyback on the parser
+        // Suggest removing a `{` we think appears in an `if`/`while` condition.
+        // We want to suggest removing a `{` only if we think we're in an `if`/`while` condition,
+        // but we have no way of tracking this in the lexer itself, so we piggyback on the parser.
         let mut in_cond = false;
         while parser.token != token::Eof {
             if let Err(diff_err) = parser.err_vcs_conflict_marker() {
@@ -249,14 +247,15 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
                 parser.token.kind,
                 token::CloseDelim(Delimiter::Brace) | token::FatArrow
             ) {
-                // end of the `if`/`while` body, or the end of a `match` guard
+                // End of the `if`/`while` body, or the end of a `match` guard.
                 in_cond = false;
             } else if in_cond && parser.token == token::OpenDelim(Delimiter::Brace) {
                 // Store the `&&` and `let` to use their spans later when creating the diagnostic
                 let maybe_andand = parser.look_ahead(1, |t| t.clone());
                 let maybe_let = parser.look_ahead(2, |t| t.clone());
                 if maybe_andand == token::OpenDelim(Delimiter::Brace) {
-                    // This might be the beginning of the `if`/`while` body (i.e., the end of the condition)
+                    // This might be the beginning of the `if`/`while` body (i.e., the end of the
+                    // condition).
                     in_cond = false;
                 } else if maybe_andand == token::AndAnd && maybe_let.is_keyword(kw::Let) {
                     let mut err = parser.dcx().struct_span_err(
@@ -288,8 +287,7 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
     }
 
     fn close_delim_err(&mut self, delim: Delimiter) -> PErr<'psess> {
-        // An unexpected closing delimiter (i.e., there is no
-        // matching opening delimiter).
+        // An unexpected closing delimiter (i.e., there is no matching opening delimiter).
         let token_str = token_to_string(&self.token);
         let msg = format!("unexpected closing delimiter: `{token_str}`");
         let mut err = self.string_reader.psess.dcx.struct_span_err(self.token.span, msg);
diff --git a/compiler/rustc_parse/src/lexer/unicode_chars.rs b/compiler/rustc_parse/src/lexer/unicode_chars.rs
index c9470151a7b..8eb299108d1 100644
--- a/compiler/rustc_parse/src/lexer/unicode_chars.rs
+++ b/compiler/rustc_parse/src/lexer/unicode_chars.rs
@@ -129,42 +129,42 @@ pub(super) const UNICODE_ARRAY: &[(char, &str, &str)] = &[
     ('。', "Ideographic Full Stop", "."),
     ('︒', "Presentation Form For Vertical Ideographic Full Stop", "."),
 
-    ('՝', "Armenian Comma", "\'"),
-    (''', "Fullwidth Apostrophe", "\'"),
-    ('‘', "Left Single Quotation Mark", "\'"),
-    ('’', "Right Single Quotation Mark", "\'"),
-    ('‛', "Single High-Reversed-9 Quotation Mark", "\'"),
-    ('′', "Prime", "\'"),
-    ('‵', "Reversed Prime", "\'"),
-    ('՚', "Armenian Apostrophe", "\'"),
-    ('׳', "Hebrew Punctuation Geresh", "\'"),
-    ('`', "Grave Accent", "\'"),
-    ('`', "Greek Varia", "\'"),
-    ('`', "Fullwidth Grave Accent", "\'"),
-    ('´', "Acute Accent", "\'"),
-    ('΄', "Greek Tonos", "\'"),
-    ('´', "Greek Oxia", "\'"),
-    ('᾽', "Greek Koronis", "\'"),
-    ('᾿', "Greek Psili", "\'"),
-    ('῾', "Greek Dasia", "\'"),
-    ('ʹ', "Modifier Letter Prime", "\'"),
-    ('ʹ', "Greek Numeral Sign", "\'"),
-    ('ˈ', "Modifier Letter Vertical Line", "\'"),
-    ('ˊ', "Modifier Letter Acute Accent", "\'"),
-    ('ˋ', "Modifier Letter Grave Accent", "\'"),
-    ('˴', "Modifier Letter Middle Grave Accent", "\'"),
-    ('ʻ', "Modifier Letter Turned Comma", "\'"),
-    ('ʽ', "Modifier Letter Reversed Comma", "\'"),
-    ('ʼ', "Modifier Letter Apostrophe", "\'"),
-    ('ʾ', "Modifier Letter Right Half Ring", "\'"),
-    ('ꞌ', "Latin Small Letter Saltillo", "\'"),
-    ('י', "Hebrew Letter Yod", "\'"),
-    ('ߴ', "Nko High Tone Apostrophe", "\'"),
-    ('ߵ', "Nko Low Tone Apostrophe", "\'"),
-    ('ᑊ', "Canadian Syllabics West-Cree P", "\'"),
-    ('ᛌ', "Runic Letter Short-Twig-Sol S", "\'"),
-    ('𖽑', "Miao Sign Aspiration", "\'"),
-    ('𖽒', "Miao Sign Reformed Voicing", "\'"),
+    ('՝', "Armenian Comma", "'"),
+    (''', "Fullwidth Apostrophe", "'"),
+    ('‘', "Left Single Quotation Mark", "'"),
+    ('’', "Right Single Quotation Mark", "'"),
+    ('‛', "Single High-Reversed-9 Quotation Mark", "'"),
+    ('′', "Prime", "'"),
+    ('‵', "Reversed Prime", "'"),
+    ('՚', "Armenian Apostrophe", "'"),
+    ('׳', "Hebrew Punctuation Geresh", "'"),
+    ('`', "Grave Accent", "'"),
+    ('`', "Greek Varia", "'"),
+    ('`', "Fullwidth Grave Accent", "'"),
+    ('´', "Acute Accent", "'"),
+    ('΄', "Greek Tonos", "'"),
+    ('´', "Greek Oxia", "'"),
+    ('᾽', "Greek Koronis", "'"),
+    ('᾿', "Greek Psili", "'"),
+    ('῾', "Greek Dasia", "'"),
+    ('ʹ', "Modifier Letter Prime", "'"),
+    ('ʹ', "Greek Numeral Sign", "'"),
+    ('ˈ', "Modifier Letter Vertical Line", "'"),
+    ('ˊ', "Modifier Letter Acute Accent", "'"),
+    ('ˋ', "Modifier Letter Grave Accent", "'"),
+    ('˴', "Modifier Letter Middle Grave Accent", "'"),
+    ('ʻ', "Modifier Letter Turned Comma", "'"),
+    ('ʽ', "Modifier Letter Reversed Comma", "'"),
+    ('ʼ', "Modifier Letter Apostrophe", "'"),
+    ('ʾ', "Modifier Letter Right Half Ring", "'"),
+    ('ꞌ', "Latin Small Letter Saltillo", "'"),
+    ('י', "Hebrew Letter Yod", "'"),
+    ('ߴ', "Nko High Tone Apostrophe", "'"),
+    ('ߵ', "Nko Low Tone Apostrophe", "'"),
+    ('ᑊ', "Canadian Syllabics West-Cree P", "'"),
+    ('ᛌ', "Runic Letter Short-Twig-Sol S", "'"),
+    ('𖽑', "Miao Sign Aspiration", "'"),
+    ('𖽒', "Miao Sign Reformed Voicing", "'"),
 
     ('᳓', "Vedic Sign Nihshvasa", "\""),
     ('"', "Fullwidth Quotation Mark", "\""),
@@ -298,6 +298,7 @@ pub(super) const UNICODE_ARRAY: &[(char, &str, &str)] = &[
     ('〉', "Right Angle Bracket", ">"),
     ('》', "Right Double Angle Bracket", ">"),
     ('>', "Fullwidth Greater-Than Sign", ">"),
+
     ('⩵', "Two Consecutive Equals Signs", "==")
 ];
 
@@ -332,7 +333,7 @@ const ASCII_ARRAY: &[(&str, &str, Option<token::TokenKind>)] = &[
     (">", "Greater-Than Sign", Some(token::Gt)),
     // FIXME: Literals are already lexed by this point, so we can't recover gracefully just by
     // spitting the correct token out.
-    ("\'", "Single Quote", None),
+    ("'", "Single Quote", None),
     ("\"", "Quotation Mark", None),
 ];
 
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index 322739be3fb..b316327a262 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -34,84 +34,41 @@ mod errors;
 
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
 
-// A bunch of utility functions of the form `parse_<thing>_from_<source>`
-// where <thing> includes crate, expr, item, stmt, tts, and one that
-// uses a HOF to parse anything, and <source> includes file and
-// `source_str`.
-
-/// A variant of 'panictry!' that works on a `Vec<Diag>` instead of a single `Diag`.
-macro_rules! panictry_buffer {
-    ($e:expr) => {{
-        use std::result::Result::{Err, Ok};
-        match $e {
-            Ok(e) => e,
-            Err(errs) => {
-                for e in errs {
-                    e.emit();
-                }
-                FatalError.raise()
+// Unwrap the result if `Ok`, otherwise emit the diagnostics and abort.
+pub fn unwrap_or_emit_fatal<T>(expr: Result<T, Vec<Diag<'_>>>) -> T {
+    match expr {
+        Ok(expr) => expr,
+        Err(errs) => {
+            for err in errs {
+                err.emit();
             }
+            FatalError.raise()
         }
-    }};
-}
-
-pub fn parse_crate_from_file<'a>(input: &Path, psess: &'a ParseSess) -> PResult<'a, ast::Crate> {
-    let mut parser = new_parser_from_file(psess, input, None);
-    parser.parse_crate_mod()
-}
-
-pub fn parse_crate_attrs_from_file<'a>(
-    input: &Path,
-    psess: &'a ParseSess,
-) -> PResult<'a, ast::AttrVec> {
-    let mut parser = new_parser_from_file(psess, input, None);
-    parser.parse_inner_attributes()
-}
-
-pub fn parse_crate_from_source_str(
-    name: FileName,
-    source: String,
-    psess: &ParseSess,
-) -> PResult<'_, ast::Crate> {
-    new_parser_from_source_str(psess, name, source).parse_crate_mod()
-}
-
-pub fn parse_crate_attrs_from_source_str(
-    name: FileName,
-    source: String,
-    psess: &ParseSess,
-) -> PResult<'_, ast::AttrVec> {
-    new_parser_from_source_str(psess, name, source).parse_inner_attributes()
-}
-
-pub fn parse_stream_from_source_str(
-    name: FileName,
-    source: String,
-    psess: &ParseSess,
-    override_span: Option<Span>,
-) -> TokenStream {
-    source_file_to_stream(psess, psess.source_map().new_source_file(name, source), override_span)
-}
-
-/// Creates a new parser from a source string.
-pub fn new_parser_from_source_str(psess: &ParseSess, name: FileName, source: String) -> Parser<'_> {
-    panictry_buffer!(maybe_new_parser_from_source_str(psess, name, source))
+    }
 }
 
-/// Creates a new parser from a source string. Returns any buffered errors from lexing the initial
-/// token stream; these must be consumed via `emit`, `cancel`, etc., otherwise a panic will occur
-/// when they are dropped.
-pub fn maybe_new_parser_from_source_str(
+/// 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<'_>>> {
-    maybe_source_file_to_parser(psess, psess.source_map().new_source_file(name, source))
+    let source_file = psess.source_map().new_source_file(name, source);
+    new_parser_from_source_file(psess, source_file)
 }
 
-/// Creates a new parser, aborting if the file doesn't exist. If a span is given, that is used on
-/// an error as the source of the problem.
-pub fn new_parser_from_file<'a>(psess: &'a ParseSess, path: &Path, sp: Option<Span>) -> Parser<'a> {
+/// Creates a new parser from a filename. On failure, the errors must be consumed via
+/// `unwrap_or_emit_fatal`, `emit`, `cancel`, etc., otherwise a panic will occur when they are
+/// dropped.
+///
+/// If a span is given, that is used on an error as the source of the problem.
+pub fn new_parser_from_file<'a>(
+    psess: &'a ParseSess,
+    path: &Path,
+    sp: Option<Span>,
+) -> Result<Parser<'a>, Vec<Diag<'a>>> {
     let source_file = psess.source_map().load_file(path).unwrap_or_else(|e| {
         let msg = format!("couldn't read {}: {}", path.display(), e);
         let mut err = psess.dcx.struct_fatal(msg);
@@ -120,40 +77,37 @@ pub fn new_parser_from_file<'a>(psess: &'a ParseSess, path: &Path, sp: Option<Sp
         }
         err.emit();
     });
-
-    panictry_buffer!(maybe_source_file_to_parser(psess, source_file))
+    new_parser_from_source_file(psess, source_file)
 }
 
 /// Given a session and a `source_file`, return a parser. Returns any buffered errors from lexing
 /// the initial token stream.
-fn maybe_source_file_to_parser(
+fn new_parser_from_source_file(
     psess: &ParseSess,
     source_file: Lrc<SourceFile>,
 ) -> Result<Parser<'_>, Vec<Diag<'_>>> {
     let end_pos = source_file.end_position();
-    let stream = maybe_file_to_stream(psess, source_file, None)?;
-    let mut parser = stream_to_parser(psess, stream, None);
+    let stream = source_file_to_stream(psess, source_file, None)?;
+    let mut parser = Parser::new(psess, stream, None);
     if parser.token == token::Eof {
         parser.token.span = Span::new(end_pos, end_pos, parser.token.span.ctxt(), None);
     }
-
     Ok(parser)
 }
 
-// Base abstractions
-
-/// Given a `source_file`, produces a sequence of token trees.
-pub fn source_file_to_stream(
+pub fn source_str_to_stream(
     psess: &ParseSess,
-    source_file: Lrc<SourceFile>,
+    name: FileName,
+    source: String,
     override_span: Option<Span>,
-) -> TokenStream {
-    panictry_buffer!(maybe_file_to_stream(psess, source_file, override_span))
+) -> Result<TokenStream, Vec<Diag<'_>>> {
+    let source_file = psess.source_map().new_source_file(name, source);
+    source_file_to_stream(psess, source_file, override_span)
 }
 
 /// Given a source file, produces a sequence of token trees. Returns any buffered errors from
 /// parsing the token stream.
-fn maybe_file_to_stream<'psess>(
+fn source_file_to_stream<'psess>(
     psess: &'psess ParseSess,
     source_file: Lrc<SourceFile>,
     override_span: Option<Span>,
@@ -165,16 +119,7 @@ fn maybe_file_to_stream<'psess>(
         ));
     });
 
-    lexer::parse_token_trees(psess, src.as_str(), source_file.start_pos, override_span)
-}
-
-/// Given a stream and the `ParseSess`, produces a parser.
-pub fn stream_to_parser<'a>(
-    psess: &'a ParseSess,
-    stream: TokenStream,
-    subparser_name: Option<&'static str>,
-) -> Parser<'a> {
-    Parser::new(psess, stream, subparser_name)
+    lexer::lex_token_trees(psess, src.as_str(), source_file.start_pos, override_span)
 }
 
 /// Runs the given subparser `f` on the tokens of the given `attr`'s item.
@@ -195,19 +140,28 @@ pub fn parse_in<'a, T>(
 pub fn fake_token_stream_for_item(psess: &ParseSess, item: &ast::Item) -> TokenStream {
     let source = pprust::item_to_string(item);
     let filename = FileName::macro_expansion_source_code(&source);
-    parse_stream_from_source_str(filename, source, psess, Some(item.span))
+    unwrap_or_emit_fatal(source_str_to_stream(psess, filename, source, Some(item.span)))
 }
 
 pub fn fake_token_stream_for_crate(psess: &ParseSess, krate: &ast::Crate) -> TokenStream {
     let source = pprust::crate_to_string_for_macros(krate);
     let filename = FileName::macro_expansion_source_code(&source);
-    parse_stream_from_source_str(filename, source, psess, Some(krate.spans.inner_span))
+    unwrap_or_emit_fatal(source_str_to_stream(
+        psess,
+        filename,
+        source,
+        Some(krate.spans.inner_span),
+    ))
 }
 
 pub fn parse_cfg_attr(
     attr: &Attribute,
     psess: &ParseSess,
 ) -> Option<(MetaItem, Vec<(AttrItem, Span)>)> {
+    const CFG_ATTR_GRAMMAR_HELP: &str = "#[cfg_attr(condition, attribute, other_attribute, ...)]";
+    const CFG_ATTR_NOTE_REF: &str = "for more information, visit \
+        <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>";
+
     match attr.get_normal_item().args {
         ast::AttrArgs::Delimited(ast::DelimArgs { dspan, delim, ref tokens })
             if !tokens.is_empty() =>
@@ -222,16 +176,12 @@ pub fn parse_cfg_attr(
                 }
             }
         }
-        _ => error_malformed_cfg_attr_missing(attr.span, psess),
+        _ => {
+            psess.dcx.emit_err(errors::MalformedCfgAttr {
+                span: attr.span,
+                sugg: CFG_ATTR_GRAMMAR_HELP,
+            });
+        }
     }
     None
 }
-
-const CFG_ATTR_GRAMMAR_HELP: &str = "#[cfg_attr(condition, attribute, other_attribute, ...)]";
-const CFG_ATTR_NOTE_REF: &str = "for more information, visit \
-    <https://doc.rust-lang.org/reference/conditional-compilation.html\
-    #the-cfg_attr-attribute>";
-
-fn error_malformed_cfg_attr_missing(span: Span, psess: &ParseSess) {
-    psess.dcx.emit_err(errors::MalformedCfgAttr { span, sugg: CFG_ATTR_GRAMMAR_HELP });
-}
diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
index a57eb70c705..4acc610d8c4 100644
--- a/compiler/rustc_parse/src/parser/attr.rs
+++ b/compiler/rustc_parse/src/parser/attr.rs
@@ -265,7 +265,7 @@ impl<'a> Parser<'a> {
     /// terminated by a semicolon.
     ///
     /// Matches `inner_attrs*`.
-    pub(crate) fn parse_inner_attributes(&mut self) -> PResult<'a, ast::AttrVec> {
+    pub fn parse_inner_attributes(&mut self) -> PResult<'a, ast::AttrVec> {
         let mut attrs = ast::AttrVec::new();
         loop {
             let start_pos: u32 = self.num_bump_calls.try_into().unwrap();
diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs
index a31e350541a..79a6cf1b541 100644
--- a/compiler/rustc_parse/src/parser/tests.rs
+++ b/compiler/rustc_parse/src/parser/tests.rs
@@ -1,5 +1,7 @@
 use crate::parser::ForceCollect;
-use crate::{new_parser_from_source_str, parser::Parser, source_file_to_stream};
+use crate::{
+    new_parser_from_source_str, parser::Parser, source_str_to_stream, unwrap_or_emit_fatal,
+};
 use ast::token::IdentIsRaw;
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Delimiter, Token};
@@ -29,7 +31,11 @@ fn psess() -> ParseSess {
 
 /// Map string to parser (via tts).
 fn string_to_parser(psess: &ParseSess, source_str: String) -> Parser<'_> {
-    new_parser_from_source_str(psess, PathBuf::from("bogofile").into(), source_str)
+    unwrap_or_emit_fatal(new_parser_from_source_str(
+        psess,
+        PathBuf::from("bogofile").into(),
+        source_str,
+    ))
 }
 
 fn create_test_handler() -> (DiagCtxt, Lrc<SourceMap>, Arc<Mutex<Vec<u8>>>) {
@@ -82,11 +88,12 @@ where
 /// Maps a string to tts, using a made-up filename.
 pub(crate) fn string_to_stream(source_str: String) -> TokenStream {
     let psess = psess();
-    source_file_to_stream(
+    unwrap_or_emit_fatal(source_str_to_stream(
         &psess,
-        psess.source_map().new_source_file(PathBuf::from("bogofile").into(), source_str),
+        PathBuf::from("bogofile").into(),
+        source_str,
         None,
-    )
+    ))
 }
 
 /// Parses a string, returns a crate.
@@ -1068,7 +1075,8 @@ fn parse_item_from_source_str(
     source: String,
     psess: &ParseSess,
 ) -> PResult<'_, Option<P<ast::Item>>> {
-    new_parser_from_source_str(psess, name, source).parse_item(ForceCollect::No)
+    unwrap_or_emit_fatal(new_parser_from_source_str(psess, name, source))
+        .parse_item(ForceCollect::No)
 }
 
 // Produces a `rustc_span::span`.
@@ -1349,7 +1357,7 @@ fn ttdelim_span() {
         source: String,
         psess: &ParseSess,
     ) -> PResult<'_, P<ast::Expr>> {
-        new_parser_from_source_str(psess, name, source).parse_expr()
+        unwrap_or_emit_fatal(new_parser_from_source_str(psess, name, source)).parse_expr()
     }
 
     create_default_session_globals_then(|| {
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index ab1dd248556..954a1ab6560 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -157,6 +157,7 @@ impl<'tcx> ReachableContext<'tcx> {
                 }
                 hir::ImplItemKind::Type(_) => false,
             },
+            Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => true,
             _ => false,
         }
     }
diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs
index 788a52faf56..6a028226631 100644
--- a/compiler/rustc_span/src/span_encoding.rs
+++ b/compiler/rustc_span/src/span_encoding.rs
@@ -216,6 +216,7 @@ impl Span {
 
     // Returns either syntactic context, if it can be retrieved without taking the interner lock,
     // or an index into the interner if it cannot.
+    #[inline]
     fn inline_ctxt(self) -> Result<SyntaxContext, usize> {
         Ok(if self.len_with_tag_or_marker != BASE_LEN_INTERNED_MARKER {
             if self.len_with_tag_or_marker & PARENT_TAG == 0 {
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 61ca0d54ca4..fe883e03c44 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -2213,6 +2213,7 @@ impl fmt::Display for IdentPrinter {
 pub struct MacroRulesNormalizedIdent(Ident);
 
 impl MacroRulesNormalizedIdent {
+    #[inline]
     pub fn new(ident: Ident) -> Self {
         Self(ident.normalize_to_macro_rules())
     }
diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs
index 1c90c171a15..01510a61405 100644
--- a/library/alloc/src/collections/linked_list.rs
+++ b/library/alloc/src/collections/linked_list.rs
@@ -1705,7 +1705,7 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> {
         unsafe {
             self.current = unlinked_node.as_ref().next;
             self.list.unlink_node(unlinked_node);
-            let unlinked_node = Box::from_raw(unlinked_node.as_ptr());
+            let unlinked_node = Box::from_raw_in(unlinked_node.as_ptr(), &self.list.alloc);
             Some(unlinked_node.element)
         }
     }
@@ -1946,7 +1946,7 @@ where
                 if (self.pred)(&mut node.as_mut().element) {
                     // `unlink_node` is okay with aliasing `element` references.
                     self.list.unlink_node(node);
-                    return Some(Box::from_raw(node.as_ptr()).element);
+                    return Some(Box::from_raw_in(node.as_ptr(), &self.list.alloc).element);
                 }
             }
         }
diff --git a/library/alloc/src/collections/linked_list/tests.rs b/library/alloc/src/collections/linked_list/tests.rs
index 8dcd59d12d9..d3744c5a9d0 100644
--- a/library/alloc/src/collections/linked_list/tests.rs
+++ b/library/alloc/src/collections/linked_list/tests.rs
@@ -1164,3 +1164,42 @@ fn test_drop_panic() {
 
     assert_eq!(unsafe { DROPS }, 8);
 }
+
+#[test]
+fn test_allocator() {
+    use core::alloc::AllocError;
+    use core::alloc::Allocator;
+    use core::alloc::Layout;
+    use core::cell::Cell;
+
+    struct A {
+        has_allocated: Cell<bool>,
+        has_deallocated: Cell<bool>,
+    }
+
+    unsafe impl Allocator for A {
+        fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
+            assert!(!self.has_allocated.get());
+            self.has_allocated.set(true);
+
+            Global.allocate(layout)
+        }
+
+        unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
+            assert!(!self.has_deallocated.get());
+            self.has_deallocated.set(true);
+
+            unsafe { Global.deallocate(ptr, layout) }
+        }
+    }
+
+    let alloc = &A { has_allocated: Cell::new(false), has_deallocated: Cell::new(false) };
+    {
+        let mut list = LinkedList::new_in(alloc);
+        list.push_back(5u32);
+        list.remove(0);
+    }
+
+    assert!(alloc.has_allocated.get());
+    assert!(alloc.has_deallocated.get());
+}
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 875c24c28e4..f3a4803e0d4 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -257,8 +257,6 @@ use core::intrinsics::abort;
 #[cfg(not(no_global_oom_handling))]
 use core::iter;
 use core::marker::{PhantomData, Unsize};
-#[cfg(not(no_global_oom_handling))]
-use core::mem::size_of_val;
 use core::mem::{self, align_of_val_raw, forget, ManuallyDrop};
 use core::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, Receiver};
 use core::panic::{RefUnwindSafe, UnwindSafe};
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 7dcaa59dcd1..5a4f9df614e 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -18,8 +18,6 @@ use core::intrinsics::abort;
 #[cfg(not(no_global_oom_handling))]
 use core::iter;
 use core::marker::{PhantomData, Unsize};
-#[cfg(not(no_global_oom_handling))]
-use core::mem::size_of_val;
 use core::mem::{self, align_of_val_raw};
 use core::ops::{CoerceUnsized, Deref, DerefPure, DispatchFromDyn, Receiver};
 use core::panic::{RefUnwindSafe, UnwindSafe};
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 6cdc1e00f47..efa0fd7b56c 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -253,7 +253,7 @@
 use crate::cmp::Ordering;
 use crate::fmt::{self, Debug, Display};
 use crate::marker::{PhantomData, Unsize};
-use crate::mem::{self, size_of};
+use crate::mem;
 use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn};
 use crate::ptr::{self, NonNull};
 
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 89e0b670995..28397fe4619 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -65,7 +65,6 @@
 
 use crate::marker::DiscriminantKind;
 use crate::marker::Tuple;
-use crate::mem::align_of;
 use crate::ptr;
 use crate::ub_checks;
 
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index 026e21586d4..4175d4a3329 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -120,12 +120,8 @@ use crate::slice;
 /// use std::mem::{self, MaybeUninit};
 ///
 /// let data = {
-///     // Create an uninitialized array of `MaybeUninit`. The `assume_init` is
-///     // safe because the type we are claiming to have initialized here is a
-///     // bunch of `MaybeUninit`s, which do not require initialization.
-///     let mut data: [MaybeUninit<Vec<u32>>; 1000] = unsafe {
-///         MaybeUninit::uninit().assume_init()
-///     };
+///     // Create an uninitialized array of `MaybeUninit`.
+///     let mut data: [MaybeUninit<Vec<u32>>; 1000] = [const { MaybeUninit::uninit() }; 1000];
 ///
 ///     // Dropping a `MaybeUninit` does nothing, so if there is a panic during this loop,
 ///     // we have a memory leak, but there is no memory safety issue.
@@ -147,10 +143,8 @@ use crate::slice;
 /// ```
 /// use std::mem::MaybeUninit;
 ///
-/// // Create an uninitialized array of `MaybeUninit`. The `assume_init` is
-/// // safe because the type we are claiming to have initialized here is a
-/// // bunch of `MaybeUninit`s, which do not require initialization.
-/// let mut data: [MaybeUninit<String>; 1000] = unsafe { MaybeUninit::uninit().assume_init() };
+/// // Create an uninitialized array of `MaybeUninit`.
+/// let mut data: [MaybeUninit<String>; 1000] = [const { MaybeUninit::uninit() }; 1000];
 /// // Count the number of elements we have assigned.
 /// let mut data_len: usize = 0;
 ///
@@ -348,8 +342,7 @@ impl<T> MaybeUninit<T> {
     #[must_use]
     #[inline(always)]
     pub const fn uninit_array<const N: usize>() -> [Self; N] {
-        // SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid.
-        unsafe { MaybeUninit::<[MaybeUninit<T>; N]>::uninit().assume_init() }
+        [const { MaybeUninit::uninit() }; N]
     }
 
     /// Creates a new `MaybeUninit<T>` in an uninitialized state, with the memory being
diff --git a/library/core/src/prelude/common.rs b/library/core/src/prelude/common.rs
index afc6817aa1d..2a0331ef7b2 100644
--- a/library/core/src/prelude/common.rs
+++ b/library/core/src/prelude/common.rs
@@ -14,6 +14,9 @@ pub use crate::ops::{Drop, Fn, FnMut, FnOnce};
 #[stable(feature = "core_prelude", since = "1.4.0")]
 #[doc(no_inline)]
 pub use crate::mem::drop;
+#[stable(feature = "size_of_prelude", since = "CURRENT_RUSTC_VERSION")]
+#[doc(no_inline)]
+pub use crate::mem::{align_of, align_of_val, size_of, size_of_val};
 
 // Re-exported types and traits
 #[stable(feature = "core_prelude", since = "1.4.0")]
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 8e3447d0b1b..6661f6ee78b 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -415,7 +415,7 @@ use crate::intrinsics;
 use crate::marker::FnPtr;
 use crate::ub_checks;
 
-use crate::mem::{self, align_of, size_of, MaybeUninit};
+use crate::mem::{self, MaybeUninit};
 
 mod alignment;
 #[unstable(feature = "ptr_alignment_type", issue = "102070")]
diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs
index 29a12f106c5..3f4305866e6 100644
--- a/library/core/src/slice/raw.rs
+++ b/library/core/src/slice/raw.rs
@@ -1,7 +1,6 @@
 //! Free functions to create `&[T]` and `&mut [T]`.
 
 use crate::array;
-use crate::mem::{align_of, size_of};
 use crate::ops::Range;
 use crate::ptr;
 use crate::ub_checks;
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index 232ec589093..482bd19705c 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -1296,7 +1296,6 @@ impl<T> AtomicPtr<T> {
     #[cfg(target_has_atomic_equal_alignment = "ptr")]
     #[unstable(feature = "atomic_from_mut", issue = "76314")]
     pub fn from_mut(v: &mut *mut T) -> &mut Self {
-        use crate::mem::align_of;
         let [] = [(); align_of::<AtomicPtr<()>>() - align_of::<*mut ()>()];
         // SAFETY:
         //  - the mutable reference guarantees unique ownership.
@@ -2286,7 +2285,6 @@ macro_rules! atomic_int {
             #[$cfg_align]
             #[unstable(feature = "atomic_from_mut", issue = "76314")]
             pub fn from_mut(v: &mut $int_type) -> &mut Self {
-                use crate::mem::align_of;
                 let [] = [(); align_of::<Self>() - align_of::<$int_type>()];
                 // SAFETY:
                 //  - the mutable reference guarantees unique ownership.
@@ -2354,7 +2352,6 @@ macro_rules! atomic_int {
             #[$cfg_align]
             #[unstable(feature = "atomic_from_mut", issue = "76314")]
             pub fn from_mut_slice(v: &mut [$int_type]) -> &mut [Self] {
-                use crate::mem::align_of;
                 let [] = [(); align_of::<Self>() - align_of::<$int_type>()];
                 // SAFETY:
                 //  - the mutable reference guarantees unique ownership.
diff --git a/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs b/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs
index 0f1719206c9..cbffbc564cf 100644
--- a/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs
@@ -96,7 +96,7 @@ where
     fn cast<U>(self) -> Self::CastPtr<U> {
         // SimdElement currently requires zero-sized metadata, so this should never fail.
         // If this ever changes, `simd_cast_ptr` should produce a post-mono error.
-        use core::{mem::size_of, ptr::Pointee};
+        use core::ptr::Pointee;
         assert_eq!(size_of::<<T as Pointee>::Metadata>(), 0);
         assert_eq!(size_of::<<U as Pointee>::Metadata>(), 0);
 
diff --git a/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs b/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs
index 7ba996d149c..6bc6ca3ac42 100644
--- a/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs
@@ -93,7 +93,7 @@ where
     fn cast<U>(self) -> Self::CastPtr<U> {
         // SimdElement currently requires zero-sized metadata, so this should never fail.
         // If this ever changes, `simd_cast_ptr` should produce a post-mono error.
-        use core::{mem::size_of, ptr::Pointee};
+        use core::ptr::Pointee;
         assert_eq!(size_of::<<T as Pointee>::Metadata>(), 0);
         assert_eq!(size_of::<<U as Pointee>::Metadata>(), 0);
 
diff --git a/library/proc_macro/src/bridge/fxhash.rs b/library/proc_macro/src/bridge/fxhash.rs
index f9f74c63fc4..9fb79eabd05 100644
--- a/library/proc_macro/src/bridge/fxhash.rs
+++ b/library/proc_macro/src/bridge/fxhash.rs
@@ -7,7 +7,6 @@
 use std::collections::HashMap;
 use std::hash::BuildHasherDefault;
 use std::hash::Hasher;
-use std::mem::size_of;
 use std::ops::BitXor;
 
 /// Type alias for a hashmap using the `fx` hash algorithm.
diff --git a/library/std/src/io/error/repr_bitpacked.rs b/library/std/src/io/error/repr_bitpacked.rs
index 6f8d5e37775..c9d3934ad70 100644
--- a/library/std/src/io/error/repr_bitpacked.rs
+++ b/library/std/src/io/error/repr_bitpacked.rs
@@ -104,7 +104,6 @@
 
 use super::{Custom, ErrorData, ErrorKind, RawOsError, SimpleMessage};
 use core::marker::PhantomData;
-use core::mem::{align_of, size_of};
 use core::ptr::{self, NonNull};
 
 // The 2 least-significant bits are used as tag.
diff --git a/library/std/src/os/unix/net/ancillary.rs b/library/std/src/os/unix/net/ancillary.rs
index 0597fdcbd72..fe8e2be9372 100644
--- a/library/std/src/os/unix/net/ancillary.rs
+++ b/library/std/src/os/unix/net/ancillary.rs
@@ -3,7 +3,7 @@
 use super::{sockaddr_un, SocketAddr};
 use crate::io::{self, IoSlice, IoSliceMut};
 use crate::marker::PhantomData;
-use crate::mem::{size_of, zeroed};
+use crate::mem::zeroed;
 use crate::os::unix::io::RawFd;
 use crate::path::Path;
 use crate::ptr::{eq, read_unaligned};
diff --git a/library/std/src/prelude/common.rs b/library/std/src/prelude/common.rs
index 01936734d75..ceee3e33c3e 100644
--- a/library/std/src/prelude/common.rs
+++ b/library/std/src/prelude/common.rs
@@ -14,6 +14,9 @@ pub use crate::ops::{Drop, Fn, FnMut, FnOnce};
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)]
 pub use crate::mem::drop;
+#[stable(feature = "size_of_prelude", since = "CURRENT_RUSTC_VERSION")]
+#[doc(no_inline)]
+pub use crate::mem::{align_of, align_of_val, size_of, size_of_val};
 
 // Re-exported types and traits
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/std/src/prelude/mod.rs b/library/std/src/prelude/mod.rs
index 0bdbab716ad..2d4639342bf 100644
--- a/library/std/src/prelude/mod.rs
+++ b/library/std/src/prelude/mod.rs
@@ -36,6 +36,10 @@
 //!   operations for both destructors and overloading `()`.
 //! * <code>[std::mem]::[drop]</code>, a convenience function for explicitly
 //!   dropping a value.
+//! * <code>[std::mem]::{[size_of], [size_of_val]}</code>, to get the size of
+//!   a type or value.
+//! * <code>[std::mem]::{[align_of], [align_of_val]}</code>, to get the
+//!   alignment of a type or value.
 //! * <code>[std::boxed]::[Box]</code>, a way to allocate values on the heap.
 //! * <code>[std::borrow]::[ToOwned]</code>, the conversion trait that defines
 //!   [`to_owned`], the generic method for creating an owned type from a
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index ca0d1fa5bd0..32dd3efa7a6 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -7,6 +7,7 @@ default-run = "bootstrap"
 
 [features]
 build-metrics = ["sysinfo"]
+bootstrap-self-test = [] # enabled in the bootstrap unit tests
 
 [lib]
 path = "src/lib.rs"
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 29b3d1669b4..aaedee65ed7 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -3053,6 +3053,7 @@ impl Step for Bootstrap {
 
         let mut cmd = Command::new(&builder.initial_cargo);
         cmd.arg("test")
+            .args(["--features", "bootstrap-self-test"])
             .current_dir(builder.src.join("src/bootstrap"))
             .env("RUSTFLAGS", "-Cdebuginfo=2")
             .env("CARGO_TARGET_DIR", builder.out.join("bootstrap"))
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 70d32f2f6d9..17e37c1ecd2 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -22,8 +22,6 @@ use crate::utils::cache::{Interned, INTERNER};
 use crate::utils::channel::{self, GitInfo};
 use crate::utils::helpers::{exe, output, t};
 use build_helper::exit;
-use build_helper::util::fail;
-use semver::Version;
 use serde::{Deserialize, Deserializer};
 use serde_derive::Deserialize;
 
@@ -2382,8 +2380,14 @@ impl Config {
         }
     }
 
-    // check rustc/cargo version is same or lower with 1 apart from the building one
+    #[cfg(feature = "bootstrap-self-test")]
+    pub fn check_stage0_version(&self, _program_path: &Path, _component_name: &'static str) {}
+
+    /// check rustc/cargo version is same or lower with 1 apart from the building one
+    #[cfg(not(feature = "bootstrap-self-test"))]
     pub fn check_stage0_version(&self, program_path: &Path, component_name: &'static str) {
+        use build_helper::util::fail;
+
         if self.dry_run() {
             return;
         }
@@ -2400,11 +2404,12 @@ impl Config {
         }
 
         let stage0_version =
-            Version::parse(stage0_output.next().unwrap().split('-').next().unwrap().trim())
-                .unwrap();
-        let source_version =
-            Version::parse(fs::read_to_string(self.src.join("src/version")).unwrap().trim())
+            semver::Version::parse(stage0_output.next().unwrap().split('-').next().unwrap().trim())
                 .unwrap();
+        let source_version = semver::Version::parse(
+            fs::read_to_string(self.src.join("src/version")).unwrap().trim(),
+        )
+        .unwrap();
         if !(source_version == stage0_version
             || (source_version.major == stage0_version.major
                 && (source_version.minor == stage0_version.minor
diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs
index c4073910623..bfb2c02860d 100644
--- a/src/bootstrap/src/core/config/tests.rs
+++ b/src/bootstrap/src/core/config/tests.rs
@@ -14,16 +14,9 @@ use std::{
 };
 
 fn parse(config: &str) -> Config {
-    Config::parse_inner(
-        &[
-            "check".to_string(),
-            "--set=build.rustc=/does/not/exist".to_string(),
-            "--set=build.cargo=/does/not/exist".to_string(),
-            "--config=/does/not/exist".to_string(),
-            "--skip-stage0-validation".to_string(),
-        ],
-        |&_| toml::from_str(&config).unwrap(),
-    )
+    Config::parse_inner(&["check".to_string(), "--config=/does/not/exist".to_string()], |&_| {
+        toml::from_str(&config).unwrap()
+    })
 }
 
 #[test]
@@ -212,10 +205,7 @@ fn override_toml_duplicate() {
     Config::parse_inner(
         &[
             "check".to_owned(),
-            "--set=build.rustc=/does/not/exist".to_string(),
-            "--set=build.cargo=/does/not/exist".to_string(),
-            "--config=/does/not/exist".to_owned(),
-            "--skip-stage0-validation".to_owned(),
+            "--config=/does/not/exist".to_string(),
             "--set=change-id=1".to_owned(),
             "--set=change-id=2".to_owned(),
         ],
@@ -238,15 +228,7 @@ fn profile_user_dist() {
             .and_then(|table: toml::Value| TomlConfig::deserialize(table))
             .unwrap()
     }
-    Config::parse_inner(
-        &[
-            "check".to_owned(),
-            "--set=build.rustc=/does/not/exist".to_string(),
-            "--set=build.cargo=/does/not/exist".to_string(),
-            "--skip-stage0-validation".to_string(),
-        ],
-        get_toml,
-    );
+    Config::parse_inner(&["check".to_owned()], get_toml);
 }
 
 #[test]
diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs
index 60f48c5923e..2b11b8c3d4f 100644
--- a/src/bootstrap/src/core/download.rs
+++ b/src/bootstrap/src/core/download.rs
@@ -9,11 +9,10 @@ use std::{
 };
 
 use build_helper::ci::CiEnv;
-use build_helper::stage0_parser::VersionMetadata;
 use xz2::bufread::XzDecoder;
 
+use crate::utils::helpers::hex_encode;
 use crate::utils::helpers::{check_run, exe, move_file, program_out_of_date};
-use crate::{core::build_steps::llvm::detect_llvm_sha, utils::helpers::hex_encode};
 use crate::{t, Config};
 
 static SHOULD_FIX_BINS_AND_DYLIBS: OnceLock<bool> = OnceLock::new();
@@ -405,9 +404,17 @@ impl Config {
         cargo_clippy
     }
 
+    #[cfg(feature = "bootstrap-self-test")]
+    pub(crate) fn maybe_download_rustfmt(&self) -> Option<PathBuf> {
+        None
+    }
+
     /// NOTE: rustfmt is a completely different toolchain than the bootstrap compiler, so it can't
     /// reuse target directories or artifacts
+    #[cfg(not(feature = "bootstrap-self-test"))]
     pub(crate) fn maybe_download_rustfmt(&self) -> Option<PathBuf> {
+        use build_helper::stage0_parser::VersionMetadata;
+
         let VersionMetadata { date, version } = self.stage0_metadata.rustfmt.as_ref()?;
         let channel = format!("{version}-{date}");
 
@@ -487,6 +494,10 @@ impl Config {
         );
     }
 
+    #[cfg(feature = "bootstrap-self-test")]
+    pub(crate) fn download_beta_toolchain(&self) {}
+
+    #[cfg(not(feature = "bootstrap-self-test"))]
     pub(crate) fn download_beta_toolchain(&self) {
         self.verbose(|| println!("downloading stage0 beta artifacts"));
 
@@ -665,7 +676,13 @@ download-rustc = false
         self.unpack(&tarball, &bin_root, prefix);
     }
 
+    #[cfg(feature = "bootstrap-self-test")]
+    pub(crate) fn maybe_download_ci_llvm(&self) {}
+
+    #[cfg(not(feature = "bootstrap-self-test"))]
     pub(crate) fn maybe_download_ci_llvm(&self) {
+        use crate::core::build_steps::llvm::detect_llvm_sha;
+
         if !self.llvm_from_ci {
             return;
         }
@@ -707,6 +724,7 @@ download-rustc = false
         }
     }
 
+    #[cfg(not(feature = "bootstrap-self-test"))]
     fn download_ci_llvm(&self, llvm_sha: &str) {
         let llvm_assertions = self.llvm_assertions;
 
diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs
index 8ffa97ab78b..ead38ebc6d5 100644
--- a/src/bootstrap/src/core/sanity.rs
+++ b/src/bootstrap/src/core/sanity.rs
@@ -8,13 +8,15 @@
 //! In theory if we get past this phase it's a bug if a build fails, but in
 //! practice that's likely not true!
 
-use std::collections::{HashMap, HashSet};
+use std::collections::HashMap;
 use std::env;
 use std::ffi::{OsStr, OsString};
 use std::fs;
 use std::path::PathBuf;
 use std::process::Command;
-use walkdir::WalkDir;
+
+#[cfg(not(feature = "bootstrap-self-test"))]
+use std::collections::HashSet;
 
 use crate::builder::Kind;
 use crate::core::config::Target;
@@ -31,6 +33,7 @@ pub struct Finder {
 // it might not yet be included in stage0. In such cases, we handle the targets missing from stage0 in this list.
 //
 // Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap).
+#[cfg(not(feature = "bootstrap-self-test"))]
 const STAGE0_MISSING_TARGETS: &[&str] = &[
     // just a dummy comment so the list doesn't get onelined
 ];
@@ -167,6 +170,7 @@ than building it.
         .map(|p| cmd_finder.must_have(p))
         .or_else(|| cmd_finder.maybe_have("reuse"));
 
+    #[cfg(not(feature = "bootstrap-self-test"))]
     let stage0_supported_target_list: HashSet<String> =
         output(Command::new(&build.config.initial_rustc).args(["--print", "target-list"]))
             .lines()
@@ -193,11 +197,11 @@ than building it.
             continue;
         }
 
-        let target_str = target.to_string();
-
         // Ignore fake targets that are only used for unit tests in bootstrap.
-        if !["A-A", "B-B", "C-C"].contains(&target_str.as_str()) {
+        #[cfg(not(feature = "bootstrap-self-test"))]
+        {
             let mut has_target = false;
+            let target_str = target.to_string();
 
             let missing_targets_hashset: HashSet<_> =
                 STAGE0_MISSING_TARGETS.iter().map(|t| t.to_string()).collect();
@@ -226,7 +230,7 @@ than building it.
                     target_filename.push(".json");
 
                     // Recursively traverse through nested directories.
-                    let walker = WalkDir::new(custom_target_path).into_iter();
+                    let walker = walkdir::WalkDir::new(custom_target_path).into_iter();
                     for entry in walker.filter_map(|e| e.ok()) {
                         has_target |= entry.file_name() == target_filename;
                     }
diff --git a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md
index ab8b4caaadf..0c5129d0efb 100644
--- a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md
@@ -12,6 +12,7 @@ overall performance.
 ## Target Maintainers
 
 * [@Lokathor](https://github.com/lokathor)
+* [@corwinkuiper](https://github.com/corwinkuiper)
 
 ## Testing
 
diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs
index 5ac1b742c38..995919f73f8 100644
--- a/src/librustdoc/clean/render_macro_matchers.rs
+++ b/src/librustdoc/clean/render_macro_matchers.rs
@@ -65,7 +65,7 @@ fn snippet_equal_to_token(tcx: TyCtxt<'_>, matcher: &TokenTree) -> Option<String
     let psess = ParseSess::new(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec());
     let file_name = source_map.span_to_filename(span);
     let mut parser =
-        match rustc_parse::maybe_new_parser_from_source_str(&psess, file_name, snippet.clone()) {
+        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());
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index a536a713921..0d4bad6921d 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -9,7 +9,7 @@ use rustc_interface::interface;
 use rustc_middle::hir::map::Map;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::TyCtxt;
-use rustc_parse::maybe_new_parser_from_source_str;
+use rustc_parse::new_parser_from_source_str;
 use rustc_parse::parser::attr::InnerAttrPolicy;
 use rustc_resolve::rustdoc::span_of_fragments;
 use rustc_session::config::{self, CrateType, ErrorOutputType};
@@ -638,7 +638,7 @@ pub(crate) fn make_test(
             let mut found_extern_crate = crate_name.is_none();
             let mut found_macro = false;
 
-            let mut parser = match maybe_new_parser_from_source_str(&psess, filename, source) {
+            let mut parser = match new_parser_from_source_str(&psess, filename, source) {
                 Ok(p) => p,
                 Err(errs) => {
                     errs.into_iter().for_each(|err| err.cancel());
@@ -818,16 +818,15 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool {
 
             let dcx = DiagCtxt::new(Box::new(emitter)).disable_warnings();
             let psess = ParseSess::with_dcx(dcx, sm);
-            let mut parser =
-                match maybe_new_parser_from_source_str(&psess, filename, source.to_owned()) {
-                    Ok(p) => p,
-                    Err(errs) => {
-                        errs.into_iter().for_each(|err| err.cancel());
-                        // If there is an unclosed delimiter, an error will be returned by the
-                        // tokentrees.
-                        return false;
-                    }
-                };
+            let mut parser = match new_parser_from_source_str(&psess, filename, source.to_owned()) {
+                Ok(p) => p,
+                Err(errs) => {
+                    errs.into_iter().for_each(|err| err.cancel());
+                    // If there is an unclosed delimiter, an error will be returned by the
+                    // tokentrees.
+                    return false;
+                }
+            };
             // If a parsing error happened, it's very likely that the attribute is incomplete.
             if let Err(e) = parser.parse_attribute(InnerAttrPolicy::Permitted) {
                 e.cancel();
diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs
index 39350f4cbbb..c185442fd55 100644
--- a/src/librustdoc/passes/lint/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs
@@ -5,7 +5,7 @@ use rustc_errors::{
     translation::{to_fluent_args, Translate},
     Applicability, DiagCtxt, DiagInner, LazyFallbackBundle,
 };
-use rustc_parse::parse_stream_from_source_str;
+use rustc_parse::{source_str_to_stream, unwrap_or_emit_fatal};
 use rustc_resolve::rustdoc::source_span_for_markdown_range;
 use rustc_session::parse::ParseSess;
 use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId, Transparency};
@@ -51,12 +51,12 @@ fn check_rust_syntax(
     let span = DUMMY_SP.apply_mark(expn_id.to_expn_id(), Transparency::Transparent);
 
     let is_empty = rustc_driver::catch_fatal_errors(|| {
-        parse_stream_from_source_str(
+        unwrap_or_emit_fatal(source_str_to_stream(
+            &psess,
             FileName::Custom(String::from("doctest")),
             source,
-            &psess,
             Some(span),
-        )
+        ))
         .is_empty()
     })
     .unwrap_or(false);
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 651f2ebaee6..c3e3c0431e6 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,7 +8,7 @@ use rustc_data_structures::sync::Lrc;
 use rustc_errors::emitter::HumanEmitter;
 use rustc_errors::{Diag, DiagCtxt};
 use rustc_lint::LateContext;
-use rustc_parse::maybe_new_parser_from_source_str;
+use rustc_parse::new_parser_from_source_str;
 use rustc_parse::parser::ForceCollect;
 use rustc_session::parse::ParseSess;
 use rustc_span::edition::Edition;
@@ -50,7 +50,7 @@ pub fn check(
                 let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
                 let psess = ParseSess::with_dcx(dcx, sm);
 
-                let mut parser = match maybe_new_parser_from_source_str(&psess, filename, code) {
+                let mut parser = match new_parser_from_source_str(&psess, filename, code) {
                     Ok(p) => p,
                     Err(errs) => {
                         errs.into_iter().for_each(Diag::cancel);
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index a2cdf800a97..d10b9c7b626 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -799,6 +799,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     "ignore-none",
     "ignore-nto",
     "ignore-nvptx64",
+    "ignore-nvptx64-nvidia-cuda",
     "ignore-openbsd",
     "ignore-pass",
     "ignore-remote",
diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs
index 607f68d12d0..e923c3cf4ad 100644
--- a/src/tools/run-make-support/src/rustc.rs
+++ b/src/tools/run-make-support/src/rustc.rs
@@ -69,6 +69,12 @@ impl Rustc {
         self
     }
 
+    /// Add a suffix in each output filename.
+    pub fn extra_filename(&mut self, suffix: &str) -> &mut Self {
+        self.cmd.arg(format!("-Cextra-filename={suffix}"));
+        self
+    }
+
     /// Specify type(s) of output files to generate.
     pub fn emit(&mut self, kinds: &str) -> &mut Self {
         self.cmd.arg(format!("--emit={kinds}"));
diff --git a/src/tools/rustfmt/src/parse/macros/mod.rs b/src/tools/rustfmt/src/parse/macros/mod.rs
index 3cf133c647c..cbcc0b2d636 100644
--- a/src/tools/rustfmt/src/parse/macros/mod.rs
+++ b/src/tools/rustfmt/src/parse/macros/mod.rs
@@ -2,7 +2,7 @@ use rustc_ast::token::{Delimiter, NonterminalKind, TokenKind};
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::{ast, ptr};
 use rustc_parse::parser::{ForceCollect, Parser, Recovery};
-use rustc_parse::{stream_to_parser, MACRO_ARGUMENTS};
+use rustc_parse::MACRO_ARGUMENTS;
 use rustc_session::parse::ParseSess;
 use rustc_span::symbol::{self, kw};
 use rustc_span::Symbol;
@@ -15,7 +15,7 @@ pub(crate) mod cfg_if;
 pub(crate) mod lazy_static;
 
 fn build_stream_parser<'a>(psess: &'a ParseSess, tokens: TokenStream) -> Parser<'a> {
-    stream_to_parser(psess, tokens, MACRO_ARGUMENTS).recovery(Recovery::Forbidden)
+    Parser::new(psess, tokens, MACRO_ARGUMENTS).recovery(Recovery::Forbidden)
 }
 
 fn build_parser<'a>(context: &RewriteContext<'a>, tokens: TokenStream) -> Parser<'a> {
diff --git a/src/tools/rustfmt/src/parse/parser.rs b/src/tools/rustfmt/src/parse/parser.rs
index 5dcdca1d953..6051241309d 100644
--- a/src/tools/rustfmt/src/parse/parser.rs
+++ b/src/tools/rustfmt/src/parse/parser.rs
@@ -4,7 +4,8 @@ use std::path::{Path, PathBuf};
 use rustc_ast::token::TokenKind;
 use rustc_ast::{ast, attr, ptr};
 use rustc_errors::Diag;
-use rustc_parse::{new_parser_from_file, parser::Parser as RawParser};
+use rustc_parse::parser::Parser as RawParser;
+use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
 use rustc_span::{sym, Span};
 use thin_vec::ThinVec;
 
@@ -50,12 +51,9 @@ impl<'a> ParserBuilder<'a> {
 
         let parser = match Self::parser(psess.inner(), input) {
             Ok(p) => p,
-            Err(db) => {
-                if let Some(diagnostics) = db {
-                    psess.emit_diagnostics(diagnostics);
-                    return Err(ParserError::ParserCreationError);
-                }
-                return Err(ParserError::ParsePanicError);
+            Err(diagnostics) => {
+                psess.emit_diagnostics(diagnostics);
+                return Err(ParserError::ParserCreationError);
             }
         };
 
@@ -65,18 +63,14 @@ impl<'a> ParserBuilder<'a> {
     fn parser(
         psess: &'a rustc_session::parse::ParseSess,
         input: Input,
-    ) -> Result<rustc_parse::parser::Parser<'a>, Option<Vec<Diag<'a>>>> {
+    ) -> Result<RawParser<'a>, Vec<Diag<'a>>> {
         match input {
-            Input::File(ref file) => catch_unwind(AssertUnwindSafe(move || {
-                new_parser_from_file(psess, file, None)
-            }))
-            .map_err(|_| None),
-            Input::Text(text) => rustc_parse::maybe_new_parser_from_source_str(
+            Input::File(ref file) => new_parser_from_file(psess, file, None),
+            Input::Text(text) => new_parser_from_source_str(
                 psess,
                 rustc_span::FileName::Custom("stdin".to_owned()),
                 text,
-            )
-            .map_err(Some),
+            ),
         }
     }
 }
@@ -111,7 +105,8 @@ impl<'a> Parser<'a> {
         span: Span,
     ) -> Result<(ast::AttrVec, ThinVec<ptr::P<ast::Item>>, Span), ParserError> {
         let result = catch_unwind(AssertUnwindSafe(|| {
-            let mut parser = new_parser_from_file(psess.inner(), path, Some(span));
+            let mut parser =
+                unwrap_or_emit_fatal(new_parser_from_file(psess.inner(), path, Some(span)));
             match parser.parse_mod(&TokenKind::Eof) {
                 Ok((a, i, spans)) => Some((a, i, spans.inner_span)),
                 Err(e) => {
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index 600ca06fcdf..3cf8d98481d 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -70,7 +70,6 @@ run-make/inaccessible-temp-dir/Makefile
 run-make/include_bytes_deps/Makefile
 run-make/incr-add-rust-src-component/Makefile
 run-make/incr-foreign-head-span/Makefile
-run-make/incr-prev-body-beyond-eof/Makefile
 run-make/incremental-debugger-visualizer/Makefile
 run-make/incremental-session-fail/Makefile
 run-make/inline-always-many-cgu/Makefile
@@ -202,7 +201,6 @@ run-make/remap-path-prefix-dwarf/Makefile
 run-make/remap-path-prefix/Makefile
 run-make/reproducible-build-2/Makefile
 run-make/reproducible-build/Makefile
-run-make/resolve-rename/Makefile
 run-make/return-non-c-like-enum-from-c/Makefile
 run-make/return-non-c-like-enum/Makefile
 run-make/rlib-chain/Makefile
@@ -232,7 +230,6 @@ run-make/static-pie/Makefile
 run-make/staticlib-blank-lib/Makefile
 run-make/staticlib-dylib-linkage/Makefile
 run-make/std-core-cycle/Makefile
-run-make/suspicious-library/Makefile
 run-make/symbol-mangling-hashed/Makefile
 run-make/symbol-visibility/Makefile
 run-make/symbols-include-type-name/Makefile
diff --git a/tests/run-make/incr-prev-body-beyond-eof/Makefile b/tests/run-make/incr-prev-body-beyond-eof/Makefile
deleted file mode 100644
index aa47552f52c..00000000000
--- a/tests/run-make/incr-prev-body-beyond-eof/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-# ignore-none no-std is not supported
-# ignore-nvptx64-nvidia-cuda FIXME: can't find crate for `std`
-
-include ../tools.mk
-
-# Tests that we don't ICE during incremental compilation after modifying a
-# function span such that its previous end line exceeds the number of lines
-# in the new file, but its start line/column and length remain the same.
-
-SRC=$(TMPDIR)/src
-INCR=$(TMPDIR)/incr
-
-all:
-	mkdir $(SRC)
-	mkdir $(INCR)
-	cp a.rs $(SRC)/main.rs
-	$(RUSTC) -C incremental=$(INCR) $(SRC)/main.rs --target $(TARGET)
-	cp b.rs $(SRC)/main.rs
-	$(RUSTC) -C incremental=$(INCR) $(SRC)/main.rs --target $(TARGET)
diff --git a/tests/run-make/incr-prev-body-beyond-eof/rmake.rs b/tests/run-make/incr-prev-body-beyond-eof/rmake.rs
new file mode 100644
index 00000000000..8aa3893727f
--- /dev/null
+++ b/tests/run-make/incr-prev-body-beyond-eof/rmake.rs
@@ -0,0 +1,27 @@
+// After modifying the span of a function, if the length of
+// the span remained the same but the end line number became different,
+// this would cause an internal compiler error (ICE), fixed in #76256.
+
+// This test compiles main.rs twice, first with end line 16 and
+// then with end line 12. If compilation is successful, the end line
+// was hashed by rustc in addition to the span length, and the fix still
+// works.
+
+//@ ignore-none
+// reason: no-std is not supported
+
+//@ ignore-nvptx64-nvidia-cuda
+// FIXME: can't find crate for `std`
+
+use run_make_support::{rustc, tmp_dir};
+use std::fs;
+
+fn main() {
+    // FIXME(Oneirical): Use run_make_support::fs_wrapper here.
+    fs::create_dir(tmp_dir().join("src")).unwrap();
+    fs::create_dir(tmp_dir().join("incr")).unwrap();
+    fs::copy("a.rs", tmp_dir().join("src/main.rs")).unwrap();
+    rustc().incremental(tmp_dir().join("incr")).input(tmp_dir().join("src/main.rs")).run();
+    fs::copy("b.rs", tmp_dir().join("src/main.rs")).unwrap();
+    rustc().incremental(tmp_dir().join("incr")).input(tmp_dir().join("src/main.rs")).run();
+}
diff --git a/tests/run-make/resolve-rename/Makefile b/tests/run-make/resolve-rename/Makefile
deleted file mode 100644
index 00f83a5d6b2..00000000000
--- a/tests/run-make/resolve-rename/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-include ../tools.mk
-
-all:
-	$(RUSTC) -C extra-filename=-hash foo.rs
-	$(RUSTC) bar.rs
-	mv $(TMPDIR)/libfoo-hash.rlib $(TMPDIR)/libfoo-another-hash.rlib
-	$(RUSTC) baz.rs
diff --git a/tests/run-make/resolve-rename/rmake.rs b/tests/run-make/resolve-rename/rmake.rs
new file mode 100644
index 00000000000..8c6e3c24714
--- /dev/null
+++ b/tests/run-make/resolve-rename/rmake.rs
@@ -0,0 +1,16 @@
+// If a library is compiled with -C extra-filename, the rust compiler
+// will take this into account when searching for libraries. However,
+// if that library is then renamed, the rust compiler should fall back
+// to its regular library location logic and not immediately fail to find
+// the renamed library.
+// See https://github.com/rust-lang/rust/pull/49253
+
+use run_make_support::{rustc, tmp_dir};
+use std::fs;
+fn main() {
+    rustc().extra_filename("-hash").input("foo.rs").run();
+    rustc().input("bar.rs").run();
+    fs::rename(tmp_dir().join("libfoo-hash.rlib"), tmp_dir().join("libfoo-another-hash.rlib"))
+        .unwrap();
+    rustc().input("baz.rs").run();
+}
diff --git a/tests/run-make/suspicious-library/Makefile b/tests/run-make/suspicious-library/Makefile
deleted file mode 100644
index 3b5ab3c53a5..00000000000
--- a/tests/run-make/suspicious-library/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# ignore-cross-compile
-include ../tools.mk
-
-all:
-	$(RUSTC) foo.rs -C prefer-dynamic
-	touch $(call DYLIB,foo-something-special)
-	touch $(call DYLIB,foo-something-special2)
-	$(RUSTC) bar.rs
diff --git a/tests/run-make/suspicious-library/rmake.rs b/tests/run-make/suspicious-library/rmake.rs
new file mode 100644
index 00000000000..9e91de70bfc
--- /dev/null
+++ b/tests/run-make/suspicious-library/rmake.rs
@@ -0,0 +1,14 @@
+// This test creates some fake dynamic libraries with nothing inside,
+// and checks if rustc avoids them and successfully compiles as a result.
+
+//@ ignore-cross-compile
+
+use run_make_support::{dynamic_lib, rustc};
+use std::fs::File;
+
+fn main() {
+    rustc().input("foo.rs").arg("-Cprefer-dynamic").run();
+    File::create(dynamic_lib("foo-something-special")).unwrap();
+    File::create(dynamic_lib("foo-something-special2")).unwrap();
+    rustc().input("bar.rs").run();
+}
diff --git a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs
index ef70e64ed7e..99cb5fc5aa1 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;
+use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal};
 use rustc_session::parse::ParseSess;
 use std::path::Path;
 
@@ -34,6 +34,6 @@ fn parse() {
 
     let path = Path::new(file!());
     let path = path.canonicalize().unwrap();
-    let mut parser = new_parser_from_file(&psess, &path, None);
+    let mut parser = unwrap_or_emit_fatal(new_parser_from_file(&psess, &path, None));
     let _ = parser.parse_crate_mod();
 }
diff --git a/tests/ui-fulldeps/pprust-expr-roundtrip.rs b/tests/ui-fulldeps/pprust-expr-roundtrip.rs
index 2b1fec94387..762ad0b79ec 100644
--- a/tests/ui-fulldeps/pprust-expr-roundtrip.rs
+++ b/tests/ui-fulldeps/pprust-expr-roundtrip.rs
@@ -36,7 +36,7 @@ use rustc_ast::mut_visit::{visit_clobber, MutVisitor};
 use rustc_ast::ptr::P;
 use rustc_ast::*;
 use rustc_ast_pretty::pprust;
-use rustc_parse::new_parser_from_source_str;
+use rustc_parse::{new_parser_from_source_str, unwrap_or_emit_fatal};
 use rustc_session::parse::ParseSess;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::Ident;
@@ -46,8 +46,9 @@ use thin_vec::{thin_vec, ThinVec};
 fn parse_expr(psess: &ParseSess, src: &str) -> Option<P<Expr>> {
     let src_as_string = src.to_string();
 
-    let mut p =
-        new_parser_from_source_str(psess, FileName::Custom(src_as_string.clone()), src_as_string);
+    let mut p = unwrap_or_emit_fatal(
+        new_parser_from_source_str(psess, FileName::Custom(src_as_string.clone()), src_as_string)
+    );
     p.parse_expr().map_err(|e| e.cancel()).ok()
 }
 
diff --git a/tests/ui/cross-crate/auxiliary/static_init_aux.rs b/tests/ui/cross-crate/auxiliary/static_init_aux.rs
index dca708733b9..832cee8d4d4 100644
--- a/tests/ui/cross-crate/auxiliary/static_init_aux.rs
+++ b/tests/ui/cross-crate/auxiliary/static_init_aux.rs
@@ -3,6 +3,12 @@ pub static F: fn() = f;
 pub static G: fn() = G0;
 pub static H: &(dyn Fn() + Sync) = &h;
 pub static I: fn() = Helper(j).mk();
+pub static K: fn() -> fn() = {
+    #[inline(never)]
+    fn k() {}
+    #[inline(always)]
+    || -> fn() { k }
+};
 
 static X: u32 = 42;
 static G0: fn() = g;
diff --git a/tests/ui/cross-crate/static-init.rs b/tests/ui/cross-crate/static-init.rs
index c4697a1d010..f8003856c5c 100644
--- a/tests/ui/cross-crate/static-init.rs
+++ b/tests/ui/cross-crate/static-init.rs
@@ -8,6 +8,7 @@ static F: fn() = aux::F;
 static G: fn() = aux::G;
 static H: &(dyn Fn() + Sync) = aux::H;
 static I: fn() = aux::I;
+static K: fn() -> fn() = aux::K;
 
 fn v() -> *const u32 {
     V
@@ -19,4 +20,5 @@ fn main() {
     G();
     H();
     I();
+    K()();
 }
diff --git a/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.rs b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.rs
new file mode 100644
index 00000000000..65e90c1ca53
--- /dev/null
+++ b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.rs
@@ -0,0 +1,38 @@
+// This test should never pass!
+
+#![feature(type_alias_impl_trait)]
+
+pub trait Captures<'a> {}
+impl<T> Captures<'_> for T {}
+
+pub struct MyTy<'a, 'b>(Option<*mut &'a &'b ()>);
+unsafe impl Send for MyTy<'_, 'static> {}
+
+pub mod step1 {
+    use super::*;
+    pub type Step1<'a, 'b: 'a> = impl Sized + Captures<'b> + 'a;
+    pub fn step1<'a, 'b: 'a>() -> Step1<'a, 'b> {
+        MyTy::<'a, 'b>(None)
+    }
+}
+
+pub mod step2 {
+    pub type Step2<'a> = impl Send + 'a;
+
+    // Although `Step2` is WF at the definition site, it's not WF in its
+    // declaration site (above). We check this in `check_opaque_meets_bounds`,
+    // which must remain sound.
+    pub fn step2<'a, 'b: 'a>() -> Step2<'a>
+        where crate::step1::Step1<'a, 'b>: Send
+    {
+        crate::step1::step1::<'a, 'b>()
+        //~^ ERROR hidden type for `Step2<'a>` captures lifetime that does not appear in bounds
+    }
+}
+
+fn step3<'a, 'b>() {
+    fn is_send<T: Send>() {}
+    is_send::<crate::step2::Step2::<'a>>();
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.stderr b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.stderr
new file mode 100644
index 00000000000..58d7f9959d3
--- /dev/null
+++ b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.stderr
@@ -0,0 +1,15 @@
+error[E0700]: hidden type for `Step2<'a>` captures lifetime that does not appear in bounds
+  --> $DIR/tait-hidden-erased-unsoundness-2.rs:28:9
+   |
+LL |     pub type Step2<'a> = impl Send + 'a;
+   |                          -------------- opaque type defined here
+...
+LL |     pub fn step2<'a, 'b: 'a>() -> Step2<'a>
+   |                      -- hidden type `Step1<'a, 'b>` captures the lifetime `'b` as defined here
+...
+LL |         crate::step1::step1::<'a, 'b>()
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0700`.
diff --git a/tests/ui/issues/issue-28344.stderr b/tests/ui/issues/issue-28344.stderr
index ddc1027c16b..d30fb3cfe58 100644
--- a/tests/ui/issues/issue-28344.stderr
+++ b/tests/ui/issues/issue-28344.stderr
@@ -52,7 +52,7 @@ error[E0599]: no function or associated item named `bitor` found for trait objec
 LL |     let g = BitXor::bitor;
    |                     ^^^^^ function or associated item not found in `dyn BitXor<_>`
    |
-help: there is a method `bitxor` with a similar name, but with different arguments
+help: there is a method `bitxor` with a similar name
   --> $SRC_DIR/core/src/ops/bit.rs:LL:COL
 
 error: aborting due to 4 previous errors; 2 warnings emitted
diff --git a/tests/ui/linkage-attr/linkage-attr-mutable-static.rs b/tests/ui/linkage-attr/linkage-attr-mutable-static.rs
index a7109c6d930..ed11947f59e 100644
--- a/tests/ui/linkage-attr/linkage-attr-mutable-static.rs
+++ b/tests/ui/linkage-attr/linkage-attr-mutable-static.rs
@@ -4,12 +4,21 @@
 #![feature(linkage)]
 
 fn main() {
+    #[rustfmt::skip]
     extern "C" {
-        #[linkage = "weak"] //~ ERROR mutable statics are not allowed with `#[linkage]`
-        static mut ABC: *const u8;
+        #[linkage = "extern_weak"] //~ ERROR extern mutable statics are not allowed with `#[linkage]`
+        static mut EXTERN_WEAK: *const u8;
     }
 
     unsafe {
-        assert_eq!(ABC as usize, 0);
+        assert_eq!(EXTERN_WEAK as usize, 0);
+    }
+
+    // static mut is fine here as this is a definition rather than declaration.
+    #[linkage = "weak"]
+    static mut WEAK_DEF: u8 = 42;
+
+    unsafe {
+        assert_eq!(WEAK_DEF, 0);
     }
 }
diff --git a/tests/ui/linkage-attr/linkage-attr-mutable-static.stderr b/tests/ui/linkage-attr/linkage-attr-mutable-static.stderr
index 4db41b62393..ad999769047 100644
--- a/tests/ui/linkage-attr/linkage-attr-mutable-static.stderr
+++ b/tests/ui/linkage-attr/linkage-attr-mutable-static.stderr
@@ -1,10 +1,10 @@
-error: mutable statics are not allowed with `#[linkage]`
-  --> $DIR/linkage-attr-mutable-static.rs:8:9
+error: extern mutable statics are not allowed with `#[linkage]`
+  --> $DIR/linkage-attr-mutable-static.rs:9:9
    |
-LL |         #[linkage = "weak"]
-   |         ^^^^^^^^^^^^^^^^^^^
+LL |         #[linkage = "extern_weak"]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: making the static mutable would allow changing which symbol the static references rather than make the target of the symbol mutable
+   = note: marking the extern static mutable would allow changing which symbol the static references rather than make the target of the symbol mutable
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/resolve/filter-intrinsics.rs b/tests/ui/resolve/filter-intrinsics.rs
index c0956ef85af..8d6d22817dc 100644
--- a/tests/ui/resolve/filter-intrinsics.rs
+++ b/tests/ui/resolve/filter-intrinsics.rs
@@ -1,6 +1,6 @@
 fn main() {
-    // Should suggest only `std::mem::size_of`
-    let _ = size_of::<usize>();
+    // Should suggest only `std::mem::transmute`
+    let _ = transmute::<usize>();
     //~^ ERROR cannot find
 
     // Should suggest `std::intrinsics::fabsf64`,
diff --git a/tests/ui/resolve/filter-intrinsics.stderr b/tests/ui/resolve/filter-intrinsics.stderr
index cc1092dd0cf..9c9e92f6d4f 100644
--- a/tests/ui/resolve/filter-intrinsics.stderr
+++ b/tests/ui/resolve/filter-intrinsics.stderr
@@ -1,12 +1,12 @@
-error[E0425]: cannot find function `size_of` in this scope
+error[E0425]: cannot find function `transmute` in this scope
   --> $DIR/filter-intrinsics.rs:3:13
    |
-LL |     let _ = size_of::<usize>();
-   |             ^^^^^^^ not found in this scope
+LL |     let _ = transmute::<usize>();
+   |             ^^^^^^^^^ not found in this scope
    |
 help: consider importing this function
    |
-LL + use std::mem::size_of;
+LL + use std::mem::transmute;
    |
 
 error[E0425]: cannot find function `fabsf64` in this scope
diff --git a/tests/ui/resolve/issue-82865.stderr b/tests/ui/resolve/issue-82865.stderr
index 9d0439d9d87..730fd6d6026 100644
--- a/tests/ui/resolve/issue-82865.stderr
+++ b/tests/ui/resolve/issue-82865.stderr
@@ -15,13 +15,6 @@ LL |     Box::z
 LL |     mac!();
    |     ------ in this macro invocation
    |
-note: if you're trying to build a new `Box<_, _>` consider using one of the following associated functions:
-      Box::<T>::new
-      Box::<T>::new_uninit
-      Box::<T>::new_zeroed
-      Box::<T>::try_new
-      and 18 others
-  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 2 previous errors
diff --git a/tests/ui/traits/item-privacy.stderr b/tests/ui/traits/item-privacy.stderr
index d08bb4745bf..50b561dfd16 100644
--- a/tests/ui/traits/item-privacy.stderr
+++ b/tests/ui/traits/item-privacy.stderr
@@ -126,14 +126,15 @@ LL |     S::B;
    |        ^ associated item not found in `S`
    |
    = help: items from traits can only be used if the trait is in scope
+help: there is a method `b` with a similar name
+  --> $DIR/item-privacy.rs:11:9
+   |
+LL |         fn b(&self) { }
+   |         ^^^^^^^^^^^
 help: trait `B` which provides `B` is implemented but not in scope; perhaps you want to import it
    |
 LL + use assoc_const::B;
    |
-help: there is a method `b` with a similar name
-   |
-LL |     S::b;
-   |        ~
 
 error[E0624]: associated constant `A` is private
   --> $DIR/item-privacy.rs:101:14