about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGeorge-lewis <george-lewis@user.noreply.github.com>2024-01-10 00:37:30 -0500
committerGeorge-lewis <george-lewis@user.noreply.github.com>2024-01-13 12:11:13 -0500
commit36a69e9d39b3dd49fefa2f84b2787a50230e0a32 (patch)
treebf367cb5d5cd412e5c8a5602bdadc1a1d9b3185c
parentb55faad3149ecf196a498ea1c0cf6195f22c9d89 (diff)
downloadrust-36a69e9d39b3dd49fefa2f84b2787a50230e0a32.tar.gz
rust-36a69e9d39b3dd49fefa2f84b2787a50230e0a32.zip
Add check for ui_testing via promoting parameters from `ParseSess` to `Session`
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs13
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs4
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs4
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs30
-rw-r--r--compiler/rustc_attr/src/builtin.rs24
-rw-r--r--compiler/rustc_builtin_macros/src/cfg.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/source_util.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/target_features.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/ops.rs6
-rw-r--r--compiler/rustc_expand/src/base.rs12
-rw-r--r--compiler/rustc_expand/src/config.rs16
-rw-r--r--compiler/rustc_expand/src/expand.rs13
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs40
-rw-r--r--compiler/rustc_expand/src/mbe/quoted.rs31
-rw-r--r--compiler/rustc_expand/src/proc_macro.rs2
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/errors.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs13
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs9
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs4
-rw-r--r--compiler/rustc_lint/src/builtin.rs5
-rw-r--r--compiler/rustc_lint/src/levels.rs4
-rw-r--r--compiler/rustc_lint/src/lints.rs6
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs15
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs3
-rw-r--r--compiler/rustc_passes/src/check_attr.rs4
-rw-r--r--compiler/rustc_passes/src/check_const.rs2
-rw-r--r--compiler/rustc_passes/src/debugger_visualizer.rs15
-rw-r--r--compiler/rustc_passes/src/entry.rs2
-rw-r--r--compiler/rustc_resolve/src/macros.rs8
-rw-r--r--compiler/rustc_session/messages.ftl2
-rw-r--r--compiler/rustc_session/src/errors.rs15
-rw-r--r--compiler/rustc_session/src/parse.rs29
-rw-r--r--compiler/rustc_session/src/session.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs43
-rw-r--r--src/librustdoc/passes/check_custom_code_classes.rs7
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs2
44 files changed, 189 insertions, 234 deletions
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index a5986f2bba5..3742cf9d881 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -48,7 +48,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             );
             if !is_stable && !self.tcx.features().asm_experimental_arch {
                 feature_err(
-                    &self.tcx.sess.parse_sess,
+                    &self.tcx.sess,
                     sym::asm_experimental_arch,
                     sp,
                     "inline assembly is not stable yet on this architecture",
@@ -63,13 +63,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             self.dcx().emit_err(AttSyntaxOnlyX86 { span: sp });
         }
         if asm.options.contains(InlineAsmOptions::MAY_UNWIND) && !self.tcx.features().asm_unwind {
-            feature_err(
-                &self.tcx.sess.parse_sess,
-                sym::asm_unwind,
-                sp,
-                "the `may_unwind` option is unstable",
-            )
-            .emit();
+            feature_err(&self.tcx.sess, sym::asm_unwind, sp, "the `may_unwind` option is unstable")
+                .emit();
         }
 
         let mut clobber_abis = FxIndexMap::default();
@@ -183,7 +178,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     InlineAsmOperand::Const { anon_const } => {
                         if !self.tcx.features().asm_const {
                             feature_err(
-                                &sess.parse_sess,
+                                sess,
                                 sym::asm_const,
                                 *op_sp,
                                 "const operands for inline assembly are unstable",
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 69704de105c..e0b1a10c82e 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -1512,7 +1512,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             Some(hir::CoroutineKind::Coroutine(_)) => {
                 if !self.tcx.features().coroutines {
                     rustc_session::parse::feature_err(
-                        &self.tcx.sess.parse_sess,
+                        &self.tcx.sess,
                         sym::coroutines,
                         span,
                         "yield syntax is experimental",
@@ -1524,7 +1524,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             None => {
                 if !self.tcx.features().coroutines {
                     rustc_session::parse::feature_err(
-                        &self.tcx.sess.parse_sess,
+                        &self.tcx.sess,
                         sym::coroutines,
                         span,
                         "yield syntax is experimental",
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index d2d42a15808..5387880b6e6 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1043,7 +1043,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         {
                             add_feature_diagnostics(
                                 &mut err,
-                                &self.tcx.sess.parse_sess,
+                                &self.tcx.sess,
                                 sym::return_type_notation,
                             );
                         }
@@ -2310,7 +2310,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     hir::ArrayLen::Infer(self.lower_node_id(c.id), self.lower_span(c.value.span))
                 } else {
                     feature_err(
-                        &self.tcx.sess.parse_sess,
+                        &self.tcx.sess,
                         sym::generic_arg_infer,
                         c.value.span,
                         "using `_` for array lengths is unstable",
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 539b520f54f..192e458775a 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -17,14 +17,12 @@ use crate::errors;
 macro_rules! gate {
     ($visitor:expr, $feature:ident, $span:expr, $explain:expr) => {{
         if !$visitor.features.$feature && !$span.allows_unstable(sym::$feature) {
-            feature_err(&$visitor.sess.parse_sess, sym::$feature, $span, $explain).emit();
+            feature_err(&$visitor.sess, sym::$feature, $span, $explain).emit();
         }
     }};
     ($visitor:expr, $feature:ident, $span:expr, $explain:expr, $help:expr) => {{
         if !$visitor.features.$feature && !$span.allows_unstable(sym::$feature) {
-            feature_err(&$visitor.sess.parse_sess, sym::$feature, $span, $explain)
-                .with_help($help)
-                .emit();
+            feature_err(&$visitor.sess, sym::$feature, $span, $explain).with_help($help).emit();
         }
     }};
 }
@@ -33,7 +31,7 @@ macro_rules! gate {
 macro_rules! gate_alt {
     ($visitor:expr, $has_feature:expr, $name:expr, $span:expr, $explain:expr) => {{
         if !$has_feature && !$span.allows_unstable($name) {
-            feature_err(&$visitor.sess.parse_sess, $name, $span, $explain).emit();
+            feature_err(&$visitor.sess, $name, $span, $explain).emit();
         }
     }};
 }
@@ -45,7 +43,7 @@ macro_rules! gate_multi {
             let spans: Vec<_> =
                 $spans.filter(|span| !span.allows_unstable(sym::$feature)).collect();
             if !spans.is_empty() {
-                feature_err(&$visitor.sess.parse_sess, sym::$feature, spans, $explain).emit();
+                feature_err(&$visitor.sess, sym::$feature, spans, $explain).emit();
             }
         }
     }};
@@ -55,7 +53,7 @@ macro_rules! gate_multi {
 macro_rules! gate_legacy {
     ($visitor:expr, $feature:ident, $span:expr, $explain:expr) => {{
         if !$visitor.features.$feature && !$span.allows_unstable(sym::$feature) {
-            feature_warn(&$visitor.sess.parse_sess, sym::$feature, $span, $explain);
+            feature_warn(&$visitor.sess, sym::$feature, $span, $explain);
         }
     }};
 }
@@ -91,14 +89,7 @@ impl<'a> PostExpansionVisitor<'a> {
         match abi::is_enabled(self.features, span, symbol_unescaped.as_str()) {
             Ok(()) => (),
             Err(abi::AbiDisabled::Unstable { feature, explain }) => {
-                feature_err_issue(
-                    &self.sess.parse_sess,
-                    feature,
-                    span,
-                    GateIssue::Language,
-                    explain,
-                )
-                .emit();
+                feature_err_issue(&self.sess, feature, span, GateIssue::Language, explain).emit();
             }
             Err(abi::AbiDisabled::Unrecognized) => {
                 if self.sess.opts.pretty.map_or(true, |ppm| ppm.needs_hir()) {
@@ -571,13 +562,8 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
                 if let Ok(snippet) = sm.span_to_snippet(span)
                     && snippet == "!"
                 {
-                    feature_err(
-                        &sess.parse_sess,
-                        sym::never_patterns,
-                        span,
-                        "`!` patterns are experimental",
-                    )
-                    .emit();
+                    feature_err(sess, sym::never_patterns, span, "`!` patterns are experimental")
+                        .emit();
                 } else {
                     let suggestion = span.shrink_to_hi();
                     sess.dcx().emit_err(errors::MatchArmWithNoBody { span, suggestion });
diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index b3f601b7595..6b903be6e5e 100644
--- a/compiler/rustc_attr/src/builtin.rs
+++ b/compiler/rustc_attr/src/builtin.rs
@@ -9,7 +9,7 @@ use rustc_macros::HashStable_Generic;
 use rustc_session::config::ExpectedValues;
 use rustc_session::lint::builtin::UNEXPECTED_CFGS;
 use rustc_session::lint::BuiltinLintDiagnostics;
-use rustc_session::parse::{feature_err, ParseSess};
+use rustc_session::parse::feature_err;
 use rustc_session::{RustcVersion, Session};
 use rustc_span::hygiene::Transparency;
 use rustc_span::{symbol::sym, symbol::Symbol, Span};
@@ -518,15 +518,15 @@ pub struct Condition {
 /// Tests if a cfg-pattern matches the cfg set
 pub fn cfg_matches(
     cfg: &ast::MetaItem,
-    sess: &ParseSess,
+    sess: &Session,
     lint_node_id: NodeId,
     features: Option<&Features>,
 ) -> bool {
     eval_condition(cfg, sess, features, &mut |cfg| {
         try_gate_cfg(cfg.name, cfg.span, sess, features);
-        match sess.check_config.expecteds.get(&cfg.name) {
+        match sess.parse_sess.check_config.expecteds.get(&cfg.name) {
             Some(ExpectedValues::Some(values)) if !values.contains(&cfg.value) => {
-                sess.buffer_lint_with_diagnostic(
+                sess.parse_sess.buffer_lint_with_diagnostic(
                     UNEXPECTED_CFGS,
                     cfg.span,
                     lint_node_id,
@@ -541,8 +541,8 @@ pub fn cfg_matches(
                     ),
                 );
             }
-            None if sess.check_config.exhaustive_names => {
-                sess.buffer_lint_with_diagnostic(
+            None if sess.parse_sess.check_config.exhaustive_names => {
+                sess.parse_sess.buffer_lint_with_diagnostic(
                     UNEXPECTED_CFGS,
                     cfg.span,
                     lint_node_id,
@@ -555,18 +555,18 @@ pub fn cfg_matches(
             }
             _ => { /* not unexpected */ }
         }
-        sess.config.contains(&(cfg.name, cfg.value))
+        sess.parse_sess.config.contains(&(cfg.name, cfg.value))
     })
 }
 
-fn try_gate_cfg(name: Symbol, span: Span, sess: &ParseSess, features: Option<&Features>) {
+fn try_gate_cfg(name: Symbol, span: Span, sess: &Session, features: Option<&Features>) {
     let gate = find_gated_cfg(|sym| sym == name);
     if let (Some(feats), Some(gated_cfg)) = (features, gate) {
         gate_cfg(gated_cfg, span, sess, feats);
     }
 }
 
-fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &ParseSess, features: &Features) {
+fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &Session, features: &Features) {
     let (cfg, feature, has_feature) = gated_cfg;
     if !has_feature(features) && !cfg_span.allows_unstable(*feature) {
         let explain = format!("`cfg({cfg})` is experimental and subject to change");
@@ -594,11 +594,11 @@ fn parse_version(s: Symbol) -> Option<RustcVersion> {
 /// evaluate individual items.
 pub fn eval_condition(
     cfg: &ast::MetaItem,
-    sess: &ParseSess,
+    sess: &Session,
     features: Option<&Features>,
     eval: &mut impl FnMut(Condition) -> bool,
 ) -> bool {
-    let dcx = &sess.dcx;
+    let dcx = &sess.parse_sess.dcx;
     match &cfg.kind {
         ast::MetaItemKind::List(mis) if cfg.name_or_empty() == sym::version => {
             try_gate_cfg(sym::version, cfg.span, sess, features);
@@ -626,7 +626,7 @@ pub fn eval_condition(
             };
 
             // See https://github.com/rust-lang/rust/issues/64796#issuecomment-640851454 for details
-            if sess.assume_incomplete_release {
+            if sess.parse_sess.assume_incomplete_release {
                 RustcVersion::CURRENT > min_version
             } else {
                 RustcVersion::CURRENT >= min_version
diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs
index 1bc2512a7b0..581d390992a 100644
--- a/compiler/rustc_builtin_macros/src/cfg.rs
+++ b/compiler/rustc_builtin_macros/src/cfg.rs
@@ -22,7 +22,7 @@ pub fn expand_cfg(
         Ok(cfg) => {
             let matches_cfg = attr::cfg_matches(
                 &cfg,
-                &cx.sess.parse_sess,
+                &cx.sess,
                 cx.current_expansion.lint_node_id,
                 Some(cx.ecfg.features),
             );
diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs
index e7d7b4a7012..43d13569d1e 100644
--- a/compiler/rustc_builtin_macros/src/source_util.rs
+++ b/compiler/rustc_builtin_macros/src/source_util.rs
@@ -107,7 +107,7 @@ pub fn expand_include<'cx>(
         return DummyResult::any(sp);
     };
     // The file will be added to the code map by the parser
-    let file = match resolve_path(&cx.sess.parse_sess, file.as_str(), sp) {
+    let file = match resolve_path(&cx.sess, file.as_str(), sp) {
         Ok(f) => f,
         Err(err) => {
             err.emit();
@@ -179,7 +179,7 @@ pub fn expand_include_str(
     let Some(file) = get_single_str_from_tts(cx, sp, tts, "include_str!") else {
         return DummyResult::any(sp);
     };
-    let file = match resolve_path(&cx.sess.parse_sess, file.as_str(), sp) {
+    let file = match resolve_path(&cx.sess, file.as_str(), sp) {
         Ok(f) => f,
         Err(err) => {
             err.emit();
@@ -213,7 +213,7 @@ pub fn expand_include_bytes(
     let Some(file) = get_single_str_from_tts(cx, sp, tts, "include_bytes!") else {
         return DummyResult::any(sp);
     };
-    let file = match resolve_path(&cx.sess.parse_sess, file.as_str(), sp) {
+    let file = match resolve_path(&cx.sess, file.as_str(), sp) {
         Ok(f) => f,
         Err(err) => {
             err.emit();
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index ace356ab153..94adc7f2acc 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -2860,7 +2860,7 @@ fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) {
 
 fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {
     match lib.cfg {
-        Some(ref cfg) => rustc_attr::cfg_matches(cfg, &sess.parse_sess, CRATE_NODE_ID, None),
+        Some(ref cfg) => rustc_attr::cfg_matches(cfg, sess, CRATE_NODE_ID, None),
         None => true,
     }
 }
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 36d7234a6ea..198b7ac4170 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -155,7 +155,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
                     Some([item]) if item.has_name(sym::linker) => {
                         if !tcx.features().used_with_arg {
                             feature_err(
-                                &tcx.sess.parse_sess,
+                                &tcx.sess,
                                 sym::used_with_arg,
                                 attr.span,
                                 "`#[used(linker)]` is currently unstable",
@@ -167,7 +167,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
                     Some([item]) if item.has_name(sym::compiler) => {
                         if !tcx.features().used_with_arg {
                             feature_err(
-                                &tcx.sess.parse_sess,
+                                &tcx.sess,
                                 sym::used_with_arg,
                                 attr.span,
                                 "`#[used(compiler)]` is currently unstable",
@@ -251,7 +251,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
                     && !attr.span.allows_unstable(sym::closure_track_caller)
                 {
                     feature_err(
-                        &tcx.sess.parse_sess,
+                        &tcx.sess,
                         sym::closure_track_caller,
                         attr.span,
                         "`#[track_caller]` on closures is currently unstable",
@@ -304,7 +304,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
                         // `#[target_feature]` on `main` and `start`.
                     } else if !tcx.features().target_feature_11 {
                         feature_err(
-                            &tcx.sess.parse_sess,
+                            &tcx.sess,
                             sym::target_feature_11,
                             attr.span,
                             "`#[target_feature(..)]` can only be applied to `unsafe` functions",
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index 0fef6bc110e..3694e41a0e0 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -82,7 +82,7 @@ pub fn from_target_feature(
             };
             if !allowed {
                 feature_err(
-                    &tcx.sess.parse_sess,
+                    &tcx.sess,
                     feature_gate.unwrap(),
                     item.span(),
                     format!("the target feature `{feature}` is currently unstable"),
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
index 02952872a93..327c91731bf 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
@@ -64,7 +64,7 @@ impl<'tcx> NonConstOp<'tcx> for FloatingPointOp {
 
     fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
         feature_err(
-            &ccx.tcx.sess.parse_sess,
+            &ccx.tcx.sess,
             sym::const_fn_floating_point_arithmetic,
             span,
             format!("floating point arithmetic is not allowed in {}s", ccx.const_kind()),
@@ -553,7 +553,7 @@ impl<'tcx> NonConstOp<'tcx> for RawMutPtrDeref {
 
     fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
         feature_err(
-            &ccx.tcx.sess.parse_sess,
+            &ccx.tcx.sess,
             sym::const_mut_refs,
             span,
             format!("dereferencing raw mutable pointers in {}s is unstable", ccx.const_kind(),),
@@ -624,7 +624,7 @@ pub mod ty {
 
         fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
             feature_err(
-                &ccx.tcx.sess.parse_sess,
+                &ccx.tcx.sess,
                 sym::const_mut_refs,
                 span,
                 format!("mutable references are not allowed in {}s", ccx.const_kind()),
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index e87f2306bc7..0a1c4430397 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -1150,7 +1150,7 @@ impl<'a> ExtCtxt<'a> {
 ///
 /// This unifies the logic used for resolving `include_X!`.
 pub fn resolve_path(
-    parse_sess: &ParseSess,
+    parse_sess: &Session,
     path: impl Into<PathBuf>,
     span: Span,
 ) -> PResult<'_, PathBuf> {
@@ -1166,7 +1166,7 @@ pub fn resolve_path(
                 .expect("attempting to resolve a file path in an external file"),
             FileName::DocTest(path, _) => path,
             other => {
-                return Err(parse_sess.dcx.create_err(errors::ResolveRelativePath {
+                return Err(parse_sess.dcx().create_err(errors::ResolveRelativePath {
                     span,
                     path: parse_sess.source_map().filename_for_diagnostics(&other).to_string(),
                 }));
@@ -1390,7 +1390,7 @@ pub fn parse_macro_name_and_helper_attrs(
 /// asserts in old versions of those crates and their wide use in the ecosystem.
 /// See issue #73345 for more details.
 /// FIXME(#73933): Remove this eventually.
-fn pretty_printing_compatibility_hack(item: &Item, sess: &ParseSess) -> bool {
+fn pretty_printing_compatibility_hack(item: &Item, sess: &Session) -> bool {
     let name = item.ident.name;
     if name == sym::ProceduralMasqueradeDummyType {
         if let ast::ItemKind::Enum(enum_def, _) = &item.kind {
@@ -1418,7 +1418,7 @@ fn pretty_printing_compatibility_hack(item: &Item, sess: &ParseSess) -> bool {
                             };
 
                             if crate_matches {
-                                sess.buffer_lint_with_diagnostic(
+                                sess.parse_sess.buffer_lint_with_diagnostic(
                                         PROC_MACRO_BACK_COMPAT,
                                         item.ident.span,
                                         ast::CRATE_NODE_ID,
@@ -1439,7 +1439,7 @@ fn pretty_printing_compatibility_hack(item: &Item, sess: &ParseSess) -> bool {
     false
 }
 
-pub(crate) fn ann_pretty_printing_compatibility_hack(ann: &Annotatable, sess: &ParseSess) -> bool {
+pub(crate) fn ann_pretty_printing_compatibility_hack(ann: &Annotatable, sess: &Session) -> bool {
     let item = match ann {
         Annotatable::Item(item) => item,
         Annotatable::Stmt(stmt) => match &stmt.kind {
@@ -1451,7 +1451,7 @@ pub(crate) fn ann_pretty_printing_compatibility_hack(ann: &Annotatable, sess: &P
     pretty_printing_compatibility_hack(item, sess)
 }
 
-pub(crate) fn nt_pretty_printing_compatibility_hack(nt: &Nonterminal, sess: &ParseSess) -> bool {
+pub(crate) fn nt_pretty_printing_compatibility_hack(nt: &Nonterminal, sess: &Session) -> bool {
     let item = match nt {
         Nonterminal::NtItem(item) => item,
         Nonterminal::NtStmt(stmt) => match &stmt.kind {
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index d015d779963..f574e81e905 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -256,12 +256,7 @@ impl<'a> StripUnconfigured<'a> {
             );
         }
 
-        if !attr::cfg_matches(
-            &cfg_predicate,
-            &self.sess.parse_sess,
-            self.lint_node_id,
-            self.features,
-        ) {
+        if !attr::cfg_matches(&cfg_predicate, &self.sess, self.lint_node_id, self.features) {
             return vec![];
         }
 
@@ -369,12 +364,7 @@ impl<'a> StripUnconfigured<'a> {
         };
         (
             parse_cfg(&meta_item, self.sess).map_or(true, |meta_item| {
-                attr::cfg_matches(
-                    meta_item,
-                    &self.sess.parse_sess,
-                    self.lint_node_id,
-                    self.features,
-                )
+                attr::cfg_matches(meta_item, &self.sess, self.lint_node_id, self.features)
             }),
             Some(meta_item),
         )
@@ -385,7 +375,7 @@ impl<'a> StripUnconfigured<'a> {
     pub(crate) fn maybe_emit_expr_attr_err(&self, attr: &Attribute) {
         if self.features.is_some_and(|features| !features.stmt_expr_attributes) {
             let mut err = feature_err(
-                &self.sess.parse_sess,
+                &self.sess,
                 sym::stmt_expr_attributes,
                 attr.span,
                 "attributes on expressions are experimental",
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index c39a3dce34e..9c411be9ff9 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -30,8 +30,8 @@ use rustc_parse::parser::{
 use rustc_parse::validate_attr;
 use rustc_session::lint::builtin::{UNUSED_ATTRIBUTES, UNUSED_DOC_COMMENTS};
 use rustc_session::lint::BuiltinLintDiagnostics;
-use rustc_session::parse::{feature_err, ParseSess};
-use rustc_session::Limit;
+use rustc_session::parse::feature_err;
+use rustc_session::{Limit, Session};
 use rustc_span::symbol::{sym, Ident};
 use rustc_span::{FileName, LocalExpnId, Span};
 
@@ -800,7 +800,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             return;
         }
         feature_err(
-            &self.cx.sess.parse_sess,
+            &self.cx.sess,
             sym::proc_macro_hygiene,
             span,
             format!("custom attributes cannot be applied to {kind}"),
@@ -810,7 +810,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
 
     fn gate_proc_macro_input(&self, annotatable: &Annotatable) {
         struct GateProcMacroInput<'a> {
-            parse_sess: &'a ParseSess,
+            sess: &'a Session,
         }
 
         impl<'ast, 'a> Visitor<'ast> for GateProcMacroInput<'a> {
@@ -820,7 +820,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                         if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _)) =>
                     {
                         feature_err(
-                            self.parse_sess,
+                            self.sess,
                             sym::proc_macro_hygiene,
                             item.span,
                             "non-inline modules in proc macro input are unstable",
@@ -835,8 +835,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         }
 
         if !self.cx.ecfg.features.proc_macro_hygiene {
-            annotatable
-                .visit_with(&mut GateProcMacroInput { parse_sess: &self.cx.sess.parse_sess });
+            annotatable.visit_with(&mut GateProcMacroInput { sess: &self.cx.sess });
         }
     }
 
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index a56c980791a..363b52aef8a 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -477,14 +477,14 @@ pub fn compile_declarative_macro(
                     let tt = mbe::quoted::parse(
                         &TokenStream::new(vec![tt.clone()]),
                         true,
-                        &sess.parse_sess,
+                        sess,
                         def.id,
                         features,
                         edition,
                     )
                     .pop()
                     .unwrap();
-                    valid &= check_lhs_nt_follows(&sess.parse_sess, def, &tt);
+                    valid &= check_lhs_nt_follows(sess, def, &tt);
                     return tt;
                 }
                 sess.dcx().span_bug(def.span, "wrong-structured lhs")
@@ -501,7 +501,7 @@ pub fn compile_declarative_macro(
                     return mbe::quoted::parse(
                         &TokenStream::new(vec![tt.clone()]),
                         false,
-                        &sess.parse_sess,
+                        sess,
                         def.id,
                         features,
                         edition,
@@ -516,12 +516,12 @@ pub fn compile_declarative_macro(
     };
 
     for rhs in &rhses {
-        valid &= check_rhs(&sess.parse_sess, rhs);
+        valid &= check_rhs(sess, rhs);
     }
 
     // don't abort iteration early, so that errors for multiple lhses can be reported
     for lhs in &lhses {
-        valid &= check_lhs_no_empty_seq(&sess.parse_sess, slice::from_ref(lhs));
+        valid &= check_lhs_no_empty_seq(sess, slice::from_ref(lhs));
     }
 
     valid &= macro_check::check_meta_variables(&sess.parse_sess, def.id, def.span, &lhses, &rhses);
@@ -588,21 +588,21 @@ pub fn compile_declarative_macro(
     (mk_syn_ext(expander), rule_spans)
 }
 
-fn check_lhs_nt_follows(sess: &ParseSess, def: &ast::Item, lhs: &mbe::TokenTree) -> bool {
+fn check_lhs_nt_follows(sess: &Session, def: &ast::Item, lhs: &mbe::TokenTree) -> bool {
     // lhs is going to be like TokenTree::Delimited(...), where the
     // entire lhs is those tts. Or, it can be a "bare sequence", not wrapped in parens.
     if let mbe::TokenTree::Delimited(.., delimited) = lhs {
         check_matcher(sess, def, &delimited.tts)
     } else {
         let msg = "invalid macro matcher; matchers must be contained in balanced delimiters";
-        sess.dcx.span_err(lhs.span(), msg);
+        sess.dcx().span_err(lhs.span(), msg);
         false
     }
     // we don't abort on errors on rejection, the driver will do that for us
     // after parsing/expansion. we can report every error in every macro this way.
 }
 
-fn is_empty_token_tree(sess: &ParseSess, seq: &mbe::SequenceRepetition) -> bool {
+fn is_empty_token_tree(sess: &Session, seq: &mbe::SequenceRepetition) -> bool {
     if seq.separator.is_some() {
         false
     } else {
@@ -621,7 +621,7 @@ fn is_empty_token_tree(sess: &ParseSess, seq: &mbe::SequenceRepetition) -> bool
                         iter.next();
                     }
                     let span = t.span.to(now.span);
-                    sess.dcx.span_note(span, "doc comments are ignored in matcher position");
+                    sess.dcx().span_note(span, "doc comments are ignored in matcher position");
                 }
                 mbe::TokenTree::Sequence(_, sub_seq)
                     if (sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore
@@ -635,7 +635,7 @@ fn is_empty_token_tree(sess: &ParseSess, seq: &mbe::SequenceRepetition) -> bool
 
 /// Checks that the lhs contains no repetition which could match an empty token
 /// tree, because then the matcher would hang indefinitely.
-fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool {
+fn check_lhs_no_empty_seq(sess: &Session, tts: &[mbe::TokenTree]) -> bool {
     use mbe::TokenTree;
     for tt in tts {
         match tt {
@@ -651,7 +651,7 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool {
             TokenTree::Sequence(span, seq) => {
                 if is_empty_token_tree(sess, seq) {
                     let sp = span.entire();
-                    sess.dcx.span_err(sp, "repetition matches empty token tree");
+                    sess.dcx().span_err(sp, "repetition matches empty token tree");
                     return false;
                 }
                 if !check_lhs_no_empty_seq(sess, &seq.tts) {
@@ -664,22 +664,22 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool {
     true
 }
 
-fn check_rhs(sess: &ParseSess, rhs: &mbe::TokenTree) -> bool {
+fn check_rhs(sess: &Session, rhs: &mbe::TokenTree) -> bool {
     match *rhs {
         mbe::TokenTree::Delimited(..) => return true,
         _ => {
-            sess.dcx.span_err(rhs.span(), "macro rhs must be delimited");
+            sess.dcx().span_err(rhs.span(), "macro rhs must be delimited");
         }
     }
     false
 }
 
-fn check_matcher(sess: &ParseSess, def: &ast::Item, matcher: &[mbe::TokenTree]) -> bool {
+fn check_matcher(sess: &Session, def: &ast::Item, matcher: &[mbe::TokenTree]) -> bool {
     let first_sets = FirstSets::new(matcher);
     let empty_suffix = TokenSet::empty();
-    let err = sess.dcx.err_count();
+    let err = sess.dcx().err_count();
     check_matcher_core(sess, def, &first_sets, matcher, &empty_suffix);
-    err == sess.dcx.err_count()
+    err == sess.dcx().err_count()
 }
 
 fn has_compile_error_macro(rhs: &mbe::TokenTree) -> bool {
@@ -1014,7 +1014,7 @@ impl<'tt> TokenSet<'tt> {
 // Requires that `first_sets` is pre-computed for `matcher`;
 // see `FirstSets::new`.
 fn check_matcher_core<'tt>(
-    sess: &ParseSess,
+    sess: &Session,
     def: &ast::Item,
     first_sets: &FirstSets<'tt>,
     matcher: &'tt [mbe::TokenTree],
@@ -1139,7 +1139,7 @@ fn check_matcher_core<'tt>(
                             name,
                             Some(NonterminalKind::PatParam { inferred: false }),
                         ));
-                        sess.buffer_lint_with_diagnostic(
+                        sess.parse_sess.buffer_lint_with_diagnostic(
                             RUST_2021_INCOMPATIBLE_OR_PATTERNS,
                             span,
                             ast::CRATE_NODE_ID,
@@ -1158,7 +1158,7 @@ fn check_matcher_core<'tt>(
                             };
 
                             let sp = next_token.span();
-                            let mut err = sess.dcx.struct_span_err(
+                            let mut err = sess.dcx().struct_span_err(
                                 sp,
                                 format!(
                                     "`${name}:{frag}` {may_be} followed by `{next}`, which \
@@ -1172,7 +1172,7 @@ fn check_matcher_core<'tt>(
                             err.span_label(sp, format!("not allowed after `{kind}` fragments"));
 
                             if kind == NonterminalKind::PatWithOr
-                                && sess.edition.at_least_rust_2021()
+                                && sess.parse_sess.edition.at_least_rust_2021()
                                 && next_token.is_token(&BinOp(token::BinOpToken::Or))
                             {
                                 let suggestion = quoted_tt_to_string(&TokenTree::MetaVarDecl(
diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs
index 889f43ed203..4824b67d277 100644
--- a/compiler/rustc_expand/src/mbe/quoted.rs
+++ b/compiler/rustc_expand/src/mbe/quoted.rs
@@ -5,7 +5,8 @@ use rustc_ast::token::{self, Delimiter, Token};
 use rustc_ast::{tokenstream, NodeId};
 use rustc_ast_pretty::pprust;
 use rustc_feature::Features;
-use rustc_session::parse::{feature_err, ParseSess};
+use rustc_session::parse::feature_err;
+use rustc_session::Session;
 use rustc_span::symbol::{kw, sym, Ident};
 
 use rustc_span::edition::Edition;
@@ -38,7 +39,7 @@ const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
 pub(super) fn parse(
     input: &tokenstream::TokenStream,
     parsing_patterns: bool,
-    sess: &ParseSess,
+    sess: &Session,
     node_id: NodeId,
     features: &Features,
     edition: Edition,
@@ -84,7 +85,7 @@ pub(super) fn parse(
                                                     "invalid fragment specifier `{}`",
                                                     frag.name
                                                 );
-                                                sess.dcx
+                                                sess.dcx()
                                                     .struct_span_err(span, msg)
                                                     .with_help(VALID_FRAGMENT_NAMES_MSG)
                                                     .emit();
@@ -113,7 +114,7 @@ pub(super) fn parse(
 }
 
 /// Asks for the `macro_metavar_expr` feature if it is not already declared
-fn maybe_emit_macro_metavar_expr_feature(features: &Features, sess: &ParseSess, span: Span) {
+fn maybe_emit_macro_metavar_expr_feature(features: &Features, sess: &Session, span: Span) {
     if !features.macro_metavar_expr {
         let msg = "meta-variable expressions are unstable";
         feature_err(sess, sym::macro_metavar_expr, span, msg).emit();
@@ -138,7 +139,7 @@ fn parse_tree<'a>(
     tree: &'a tokenstream::TokenTree,
     outer_trees: &mut impl Iterator<Item = &'a tokenstream::TokenTree>,
     parsing_patterns: bool,
-    sess: &ParseSess,
+    sess: &Session,
     node_id: NodeId,
     features: &Features,
     edition: Edition,
@@ -174,7 +175,8 @@ fn parse_tree<'a>(
                                 // The delimiter is `{`. This indicates the beginning
                                 // of a meta-variable expression (e.g. `${count(ident)}`).
                                 // Try to parse the meta-variable expression.
-                                match MetaVarExpr::parse(tts, delim_span.entire(), sess) {
+                                match MetaVarExpr::parse(tts, delim_span.entire(), &sess.parse_sess)
+                                {
                                     Err(err) => {
                                         err.emit();
                                         // Returns early the same read `$` to avoid spanning
@@ -195,7 +197,7 @@ fn parse_tree<'a>(
                             _ => {
                                 let tok = pprust::token_kind_to_string(&token::OpenDelim(delim));
                                 let msg = format!("expected `(` or `{{`, found `{tok}`");
-                                sess.dcx.span_err(delim_span.entire(), msg);
+                                sess.dcx().span_err(delim_span.entire(), msg);
                             }
                         }
                     }
@@ -244,7 +246,7 @@ fn parse_tree<'a>(
                 Some(tokenstream::TokenTree::Token(token, _)) => {
                     let msg =
                         format!("expected identifier, found `{}`", pprust::token_to_string(token),);
-                    sess.dcx.span_err(token.span, msg);
+                    sess.dcx().span_err(token.span, msg);
                     TokenTree::MetaVar(token.span, Ident::empty())
                 }
 
@@ -313,7 +315,7 @@ fn parse_kleene_op<'a>(
 fn parse_sep_and_kleene_op<'a>(
     input: &mut impl Iterator<Item = &'a tokenstream::TokenTree>,
     span: Span,
-    sess: &ParseSess,
+    sess: &Session,
 ) -> (Option<Token>, KleeneToken) {
     // We basically look at two token trees here, denoted as #1 and #2 below
     let span = match parse_kleene_op(input, span) {
@@ -325,7 +327,7 @@ fn parse_sep_and_kleene_op<'a>(
             // #2 is the `?` Kleene op, which does not take a separator (error)
             Ok(Ok((KleeneOp::ZeroOrOne, span))) => {
                 // Error!
-                sess.dcx.span_err(
+                sess.dcx().span_err(
                     token.span,
                     "the `?` macro repetition operator does not take a separator",
                 );
@@ -346,7 +348,7 @@ fn parse_sep_and_kleene_op<'a>(
     };
 
     // If we ever get to this point, we have experienced an "unexpected token" error
-    sess.dcx.span_err(span, "expected one of: `*`, `+`, or `?`");
+    sess.dcx().span_err(span, "expected one of: `*`, `+`, or `?`");
 
     // Return a dummy
     (None, KleeneToken::new(KleeneOp::ZeroOrMore, span))
@@ -355,9 +357,10 @@ fn parse_sep_and_kleene_op<'a>(
 // `$$` or a meta-variable is the lhs of a macro but shouldn't.
 //
 // For example, `macro_rules! foo { ( ${length()} ) => {} }`
-fn span_dollar_dollar_or_metavar_in_the_lhs_err(sess: &ParseSess, token: &Token) {
-    sess.dcx.span_err(token.span, format!("unexpected token: {}", pprust::token_to_string(token)));
-    sess.dcx.span_note(
+fn span_dollar_dollar_or_metavar_in_the_lhs_err(sess: &Session, token: &Token) {
+    sess.dcx()
+        .span_err(token.span, format!("unexpected token: {}", pprust::token_to_string(token)));
+    sess.dcx().span_note(
         token.span,
         "`$$` and meta-variable expressions are not allowed inside macro parameter definitions",
     );
diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs
index a1d21361957..2233cad2e63 100644
--- a/compiler/rustc_expand/src/proc_macro.rs
+++ b/compiler/rustc_expand/src/proc_macro.rs
@@ -119,7 +119,7 @@ impl MultiItemModifier for DeriveProcMacro {
         // We need special handling for statement items
         // (e.g. `fn foo() { #[derive(Debug)] struct Bar; }`)
         let is_stmt = matches!(item, Annotatable::Stmt(..));
-        let hack = crate::base::ann_pretty_printing_compatibility_hack(&item, &ecx.sess.parse_sess);
+        let hack = crate::base::ann_pretty_printing_compatibility_hack(&item, &ecx.sess);
         let input = if hack {
             let nt = match item {
                 Annotatable::Item(item) => token::NtItem(item),
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 6392894fea2..3a78bd94505 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -258,7 +258,7 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre
                     // represented as a delimited group.
                     // FIXME: It needs to be removed, but there are some
                     // compatibility issues (see #73345).
-                    if crate::base::nt_pretty_printing_compatibility_hack(&nt.0, rustc.sess()) {
+                    if crate::base::nt_pretty_printing_compatibility_hack(&nt.0, rustc.ecx.sess) {
                         trees.extend(Self::from_internal((stream, rustc)));
                     } else {
                         trees.push(TokenTree::Group(Group {
diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs
index 7b23b74f829..bfe88df4e1a 100644
--- a/compiler/rustc_hir_analysis/src/astconv/errors.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs
@@ -59,7 +59,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             if trait_segment.args().parenthesized == hir::GenericArgsParentheses::ParenSugar {
                 // For now, require that parenthetical notation be used only with `Fn()` etc.
                 feature_err(
-                    &self.tcx().sess.parse_sess,
+                    &self.tcx().sess,
                     sym::unboxed_closures,
                     span,
                     "parenthetical notation is only stable when used with `Fn`-family traits",
@@ -75,7 +75,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         if trait_segment.args().parenthesized != hir::GenericArgsParentheses::ParenSugar {
             // For now, require that parenthetical notation be used only with `Fn()` etc.
             let mut err = feature_err(
-                &sess.parse_sess,
+                sess,
                 sym::unboxed_closures,
                 span,
                 "the precise format of `Fn`-family traits' type parameters is subject to change",
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 6265ddafef0..77914802bf7 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -996,7 +996,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
 
     if adt.is_union() && !tcx.features().transparent_unions {
         feature_err(
-            &tcx.sess.parse_sess,
+            &tcx.sess,
             sym::transparent_unions,
             tcx.def_span(adt.did()),
             "transparent unions are unstable",
@@ -1128,7 +1128,7 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) {
     if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
         if !tcx.features().repr128 {
             feature_err(
-                &tcx.sess.parse_sess,
+                &tcx.sess,
                 sym::repr128,
                 tcx.def_span(def_id),
                 "repr with 128-bit type is unstable",
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 3b05eaedf34..28c8f846c23 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -293,7 +293,7 @@ fn default_body_is_unstable(
 
     rustc_session::parse::add_feature_diagnostics_for_issue(
         &mut err,
-        &tcx.sess.parse_sess,
+        &tcx.sess,
         feature,
         rustc_feature::GateIssue::Library(issue),
         false,
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 59c72227144..4772bae58c4 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -1591,7 +1591,7 @@ fn check_method_receiver<'tcx>(
             return Err(if receiver_is_valid(wfcx, span, receiver_ty, self_ty, true) {
                 // Report error; would have worked with `arbitrary_self_types`.
                 feature_err(
-                    &tcx.sess.parse_sess,
+                    &tcx.sess,
                     sym::arbitrary_self_types,
                     span,
                     format!(
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 3d8390d1946..4f049f699e6 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -1189,12 +1189,13 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                         && !self.tcx.asyncness(lifetime_ref.hir_id.owner.def_id).is_async()
                         && !self.tcx.features().anonymous_lifetime_in_impl_trait
                     {
-                        let mut diag = rustc_session::parse::feature_err(
-                            &self.tcx.sess.parse_sess,
-                            sym::anonymous_lifetime_in_impl_trait,
-                            lifetime_ref.ident.span,
-                            "anonymous lifetimes in `impl Trait` are unstable",
-                        );
+                        let mut diag: rustc_errors::DiagnosticBuilder<'_> =
+                            rustc_session::parse::feature_err(
+                                &self.tcx.sess,
+                                sym::anonymous_lifetime_in_impl_trait,
+                                lifetime_ref.ident.span,
+                                "anonymous lifetimes in `impl Trait` are unstable",
+                            );
 
                         if let Some(generics) =
                             self.tcx.hir().get_generics(lifetime_ref.hir_id.owner.def_id)
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index b936b0c0805..bfa9dc42422 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -639,7 +639,7 @@ fn check_feature_inherent_assoc_ty(tcx: TyCtxt<'_>, span: Span) {
         use rustc_session::parse::feature_err;
         use rustc_span::symbol::sym;
         feature_err(
-            &tcx.sess.parse_sess,
+            &tcx.sess,
             sym::inherent_associated_types,
             span,
             "inherent associated types are unstable",
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index dfc54ac5b23..23465fb1710 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -133,13 +133,8 @@ fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi
         // Using this ABI would be ok, if the feature for additional ABI support was enabled.
         // Return CONVENTIONS_STABLE, because we want the other error to look the same.
         (false, true) => {
-            feature_err(
-                &tcx.sess.parse_sess,
-                sym::extended_varargs_abi_support,
-                span,
-                UNSTABLE_EXPLAIN,
-            )
-            .emit();
+            feature_err(&tcx.sess, sym::extended_varargs_abi_support, span, UNSTABLE_EXPLAIN)
+                .emit();
             CONVENTIONS_STABLE
         }
 
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 0b266202b26..e9d373119fa 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -704,7 +704,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
 
         if has_unsized_tuple_coercion && !self.tcx.features().unsized_tuple_coercion {
             feature_err(
-                &self.tcx.sess.parse_sess,
+                &self.tcx.sess,
                 sym::unsized_tuple_coercion,
                 self.cause.span,
                 "unsized tuple coercion is not stable enough for use and is subject to change",
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index fdad998c451..af47455c16d 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1865,7 +1865,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         (ty::Adt(adt, _), ty::Adt(base_adt, _)) if adt == base_adt);
                     if self.tcx.sess.is_nightly_build() && same_adt {
                         feature_err(
-                            &self.tcx.sess.parse_sess,
+                            &self.tcx.sess,
                             sym::type_changing_struct_update,
                             base_expr.span,
                             "type changing struct updating is experimental",
@@ -3262,7 +3262,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                     if !self.tcx.features().offset_of_enum {
                         rustc_session::parse::feature_err(
-                            &self.tcx.sess.parse_sess,
+                            &self.tcx.sess,
                             sym::offset_of_enum,
                             ident.span,
                             "using enums in offset_of is experimental",
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 8d2f2aaca55..5e1f2ed11ac 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -1306,10 +1306,7 @@ impl<'tcx> LateLintPass<'tcx> for UngatedAsyncFnTrackCaller {
             cx.emit_spanned_lint(
                 UNGATED_ASYNC_FN_TRACK_CALLER,
                 attr.span,
-                BuiltinUngatedAsyncFnTrackCaller {
-                    label: span,
-                    parse_sess: &cx.tcx.sess.parse_sess,
-                },
+                BuiltinUngatedAsyncFnTrackCaller { label: span, session: &cx.tcx.sess },
             );
         }
     }
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index 3c2d0c7b205..b98b1a2935c 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -786,7 +786,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                             if let ast::LitKind::Str(rationale, _) = name_value.kind {
                                 if !self.features.lint_reasons {
                                     feature_err(
-                                        &self.sess.parse_sess,
+                                        &self.sess,
                                         sym::lint_reasons,
                                         item.span,
                                         "lint reasons are experimental",
@@ -1074,7 +1074,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                             lint.note(fluent::lint_note);
                             rustc_session::parse::add_feature_diagnostics_for_issue(
                                 lint,
-                                &self.sess.parse_sess,
+                                &self.sess,
                                 feature,
                                 GateIssue::Language,
                                 lint_from_cli,
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index f370c4392b3..73db5790c2b 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -13,7 +13,7 @@ use rustc_macros::{LintDiagnostic, Subdiagnostic};
 use rustc_middle::ty::{
     inhabitedness::InhabitedPredicate, Clause, PolyExistentialTraitRef, Ty, TyCtxt,
 };
-use rustc_session::parse::ParseSess;
+use rustc_session::Session;
 use rustc_span::{edition::Edition, sym, symbol::Ident, Span, Symbol};
 
 use crate::{
@@ -235,7 +235,7 @@ pub struct BuiltinUnstableFeatures;
 // lint_ungated_async_fn_track_caller
 pub struct BuiltinUngatedAsyncFnTrackCaller<'a> {
     pub label: Span,
-    pub parse_sess: &'a ParseSess,
+    pub session: &'a Session,
 }
 
 impl<'a> DecorateLint<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> {
@@ -243,7 +243,7 @@ impl<'a> DecorateLint<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> {
         diag.span_label(self.label, fluent::lint_label);
         rustc_session::parse::add_feature_diagnostics(
             diag,
-            self.parse_sess,
+            self.session,
             sym::async_fn_track_caller,
         );
     }
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index a639a887544..45cae7b5d62 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -82,7 +82,7 @@ pub(crate) fn collect(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> Vec<NativeLib>
 
 pub(crate) fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {
     match lib.cfg {
-        Some(ref cfg) => attr::cfg_matches(cfg, &sess.parse_sess, CRATE_NODE_ID, None),
+        Some(ref cfg) => attr::cfg_matches(cfg, sess, CRATE_NODE_ID, None),
         None => true,
     }
 }
@@ -163,7 +163,7 @@ impl<'tcx> Collector<'tcx> {
                             "link-arg" => {
                                 if !features.link_arg_attribute {
                                     feature_err(
-                                        &sess.parse_sess,
+                                        sess,
                                         sym::link_arg_attribute,
                                         span,
                                         "link kind `link-arg` is unstable",
@@ -206,13 +206,8 @@ impl<'tcx> Collector<'tcx> {
                             continue;
                         };
                         if !features.link_cfg {
-                            feature_err(
-                                &sess.parse_sess,
-                                sym::link_cfg,
-                                item.span(),
-                                "link cfg is unstable",
-                            )
-                            .emit();
+                            feature_err(sess, sym::link_cfg, item.span(), "link cfg is unstable")
+                                .emit();
                         }
                         cfg = Some(link_cfg.clone());
                     }
@@ -277,7 +272,7 @@ impl<'tcx> Collector<'tcx> {
                     macro report_unstable_modifier($feature: ident) {
                         if !features.$feature {
                             feature_err(
-                                &sess.parse_sess,
+                                sess,
                                 sym::$feature,
                                 span,
                                 format!("linking modifier `{modifier}` is unstable"),
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index 90b479cf2f4..efe7bdfa06d 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -116,8 +116,7 @@ pub fn report_unstable(
     if is_soft {
         soft_handler(SOFT_UNSTABLE, span, msg)
     } else {
-        let mut err =
-            feature_err_issue(&sess.parse_sess, feature, span, GateIssue::Library(issue), msg);
+        let mut err = feature_err_issue(sess, feature, span, GateIssue::Library(issue), msg);
         if let Some((inner_types, msg, sugg, applicability)) = suggestion {
             err.span_suggestion(inner_types, msg, sugg, applicability);
         }
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index e4bbc9eeaf7..20ed2573e3a 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -1170,7 +1170,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         sym::rust_logo => {
                             if !self.tcx.features().rustdoc_internals {
                                 feature_err(
-                                    &self.tcx.sess.parse_sess,
+                                    &self.tcx.sess,
                                     sym::rustdoc_internals,
                                     meta.span(),
                                     "the `#[doc(rust_logo)]` attribute is used for Rust branding",
@@ -1815,7 +1815,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         (target, self.tcx.features().fn_align)
                     {
                         feature_err(
-                            &self.tcx.sess.parse_sess,
+                            &self.tcx.sess,
                             sym::fn_align,
                             hint.span(),
                             "`repr(align)` attributes on functions are unstable",
diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs
index 3e3f2771f5f..3676eb92a3f 100644
--- a/compiler/rustc_passes/src/check_const.rs
+++ b/compiler/rustc_passes/src/check_const.rs
@@ -147,7 +147,7 @@ impl<'tcx> CheckConstVisitor<'tcx> {
             [missing_primary, ref missing_secondary @ ..] => {
                 let msg =
                     format!("{} is not allowed in a `{}`", expr.name(), const_kind.keyword_name());
-                let mut err = feature_err(&tcx.sess.parse_sess, *missing_primary, span, msg);
+                let mut err = feature_err(&tcx.sess, *missing_primary, span, msg);
 
                 // If multiple feature gates would be required to enable this expression, include
                 // them as help messages. Don't emit a separate error for each missing feature gate.
diff --git a/compiler/rustc_passes/src/debugger_visualizer.rs b/compiler/rustc_passes/src/debugger_visualizer.rs
index 42e929bde2c..4bfe6be5493 100644
--- a/compiler/rustc_passes/src/debugger_visualizer.rs
+++ b/compiler/rustc_passes/src/debugger_visualizer.rs
@@ -45,14 +45,13 @@ impl DebuggerVisualizerCollector<'_> {
                     }
                 };
 
-            let file =
-                match resolve_path(&self.sess.parse_sess, visualizer_path.as_str(), attr.span) {
-                    Ok(file) => file,
-                    Err(err) => {
-                        err.emit();
-                        return;
-                    }
-                };
+            let file = match resolve_path(&self.sess, visualizer_path.as_str(), attr.span) {
+                Ok(file) => file,
+                Err(err) => {
+                    err.emit();
+                    return;
+                }
+            };
 
             match std::fs::read(&file) {
                 Ok(contents) => {
diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs
index ed26b45a936..a9d0e0d2dd3 100644
--- a/compiler/rustc_passes/src/entry.rs
+++ b/compiler/rustc_passes/src/entry.rs
@@ -135,7 +135,7 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) -> Option<(DefId,
             if main_def.is_import && !tcx.features().imported_main {
                 let span = main_def.span;
                 feature_err(
-                    &tcx.sess.parse_sess,
+                    &tcx.sess,
                     sym::imported_main,
                     span,
                     "using an imported function as entry point `main` is experimental",
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 66ecaeb4449..c9a26a7ca78 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -594,13 +594,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             if soft_custom_inner_attributes_gate {
                 self.tcx.sess.parse_sess.buffer_lint(SOFT_UNSTABLE, path.span, node_id, msg);
             } else {
-                feature_err(
-                    &self.tcx.sess.parse_sess,
-                    sym::custom_inner_attributes,
-                    path.span,
-                    msg,
-                )
-                .emit();
+                feature_err(&self.tcx.sess, sym::custom_inner_attributes, path.span, msg).emit();
             }
         }
 
diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl
index d9e1082eb41..53bdef6dfa0 100644
--- a/compiler/rustc_session/messages.ftl
+++ b/compiler/rustc_session/messages.ftl
@@ -25,7 +25,7 @@ session_feature_diagnostic_help =
     add `#![feature({$feature})]` to the crate attributes to enable
 
 session_feature_suggest_upgrade_compiler =
-    this compiler is version {$version} built on {$date}, consider upgrading?
+    this compiler was built on {$date}; consider upgrading it if it is out of date
 
 session_file_is_not_writeable = output file {$file} is not writeable -- check its permissions
 
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index 24782b41cc8..21a206798af 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -1,6 +1,5 @@
 use std::num::NonZeroU32;
 
-use crate::parse::ParseSess;
 use rustc_ast::token;
 use rustc_ast::util::literal::LitError;
 use rustc_errors::{
@@ -10,6 +9,8 @@ use rustc_macros::Diagnostic;
 use rustc_span::{BytePos, Span, Symbol};
 use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTriple};
 
+use crate::parse::ParseSess;
+
 pub struct FeatureGateError {
     pub span: MultiSpan,
     pub explain: DiagnosticMessage,
@@ -33,16 +34,18 @@ pub struct FeatureDiagnosticForIssue {
 #[derive(Subdiagnostic)]
 #[note(session_feature_suggest_upgrade_compiler)]
 pub struct SuggestUpgradeCompiler {
-    version: &'static str,
     date: &'static str,
 }
 
 impl SuggestUpgradeCompiler {
-    pub fn new() -> Self {
-        let version = option_env!("CFG_VERSION").unwrap_or("unknown");
-        let date = option_env!("CFG_VER_DATE").unwrap_or("unknown");
+    pub fn ui_testing() -> Self {
+        Self { date: "YYYY-MM-DD" }
+    }
+
+    pub fn new() -> Option<Self> {
+        let date = option_env!("CFG_VER_DATE")?;
 
-        Self { version, date }
+        Some(Self { date })
     }
 }
 
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index 39cc194fd6f..d4f58cceb2f 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -9,6 +9,7 @@ use crate::errors::{
 use crate::lint::{
     builtin::UNSTABLE_SYNTAX_PRE_EXPANSION, BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId,
 };
+use crate::Session;
 use rustc_ast::node_id::NodeId;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc};
@@ -80,7 +81,7 @@ impl SymbolGallery {
 /// The `feature`'s `Symbol` is the one you used in `unstable.rs` and `rustc_span::symbols`.
 #[track_caller]
 pub fn feature_err(
-    sess: &ParseSess,
+    sess: &Session,
     feature: Symbol,
     span: impl Into<MultiSpan>,
     explain: impl Into<DiagnosticMessage>,
@@ -94,7 +95,7 @@ pub fn feature_err(
 /// Almost always, you want to use this for a language feature. If so, prefer `feature_err`.
 #[track_caller]
 pub fn feature_err_issue(
-    sess: &ParseSess,
+    sess: &Session,
     feature: Symbol,
     span: impl Into<MultiSpan>,
     issue: GateIssue,
@@ -104,12 +105,14 @@ pub fn feature_err_issue(
 
     // Cancel an earlier warning for this same error, if it exists.
     if let Some(span) = span.primary_span() {
-        if let Some(err) = sess.dcx.steal_diagnostic(span, StashKey::EarlySyntaxWarning) {
+        if let Some(err) = sess.parse_sess.dcx.steal_diagnostic(span, StashKey::EarlySyntaxWarning)
+        {
             err.cancel()
         }
     }
 
-    let mut err = sess.dcx.create_err(FeatureGateError { span, explain: explain.into() });
+    let mut err =
+        sess.parse_sess.dcx.create_err(FeatureGateError { span, explain: explain.into() });
     add_feature_diagnostics_for_issue(&mut err, sess, feature, issue, false);
     err
 }
@@ -118,7 +121,7 @@ pub fn feature_err_issue(
 ///
 /// This diagnostic is only a warning and *does not cause compilation to fail*.
 #[track_caller]
-pub fn feature_warn(sess: &ParseSess, feature: Symbol, span: Span, explain: &'static str) {
+pub fn feature_warn(sess: &Session, feature: Symbol, span: Span, explain: &'static str) {
     feature_warn_issue(sess, feature, span, GateIssue::Language, explain);
 }
 
@@ -132,13 +135,13 @@ pub fn feature_warn(sess: &ParseSess, feature: Symbol, span: Span, explain: &'st
 #[allow(rustc::untranslatable_diagnostic)]
 #[track_caller]
 pub fn feature_warn_issue(
-    sess: &ParseSess,
+    sess: &Session,
     feature: Symbol,
     span: Span,
     issue: GateIssue,
     explain: &'static str,
 ) {
-    let mut err = sess.dcx.struct_span_warn(span, explain);
+    let mut err = sess.parse_sess.dcx.struct_span_warn(span, explain);
     add_feature_diagnostics_for_issue(&mut err, sess, feature, issue, false);
 
     // Decorate this as a future-incompatibility lint as in rustc_middle::lint::struct_lint_level
@@ -153,7 +156,7 @@ pub fn feature_warn_issue(
 }
 
 /// Adds the diagnostics for a feature to an existing error.
-pub fn add_feature_diagnostics(err: &mut Diagnostic, sess: &ParseSess, feature: Symbol) {
+pub fn add_feature_diagnostics(err: &mut Diagnostic, sess: &Session, feature: Symbol) {
     add_feature_diagnostics_for_issue(err, sess, feature, GateIssue::Language, false);
 }
 
@@ -164,7 +167,7 @@ pub fn add_feature_diagnostics(err: &mut Diagnostic, sess: &ParseSess, feature:
 /// `add_feature_diagnostics`.
 pub fn add_feature_diagnostics_for_issue(
     err: &mut Diagnostic,
-    sess: &ParseSess,
+    sess: &Session,
     feature: Symbol,
     issue: GateIssue,
     feature_from_cli: bool,
@@ -174,14 +177,18 @@ pub fn add_feature_diagnostics_for_issue(
     }
 
     // #23973: do not suggest `#![feature(...)]` if we are in beta/stable
-    if sess.unstable_features.is_nightly_build() {
+    if sess.parse_sess.unstable_features.is_nightly_build() {
         if feature_from_cli {
             err.subdiagnostic(CliFeatureDiagnosticHelp { feature });
         } else {
             err.subdiagnostic(FeatureDiagnosticHelp { feature });
         }
 
-        err.subdiagnostic(SuggestUpgradeCompiler::new());
+        if sess.opts.unstable_opts.ui_testing {
+            err.subdiagnostic(SuggestUpgradeCompiler::ui_testing());
+        } else if let Some(suggestion) = SuggestUpgradeCompiler::new() {
+            err.subdiagnostic(suggestion);
+        }
     }
 }
 
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 210dc9e0145..1c3d5a3cb88 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -318,7 +318,7 @@ impl Session {
         if err.code.is_none() {
             err.code(error_code!(E0658));
         }
-        add_feature_diagnostics(&mut err, &self.parse_sess, feature);
+        add_feature_diagnostics(&mut err, self, feature);
         err
     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
index 100c9a70aaa..532e2cb36e3 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
@@ -408,7 +408,7 @@ impl<'tcx> OnUnimplementedDirective {
                 .ok_or_else(|| tcx.dcx().emit_err(EmptyOnClauseInOnUnimplemented { span }))?
                 .meta_item()
                 .ok_or_else(|| tcx.dcx().emit_err(InvalidOnClauseInOnUnimplemented { span }))?;
-            attr::eval_condition(cond, &tcx.sess.parse_sess, Some(tcx.features()), &mut |cfg| {
+            attr::eval_condition(cond, &tcx.sess, Some(tcx.features()), &mut |cfg| {
                 if let Some(value) = cfg.value
                     && let Err(guar) = parse_value(value, cfg.span)
                 {
@@ -682,31 +682,22 @@ impl<'tcx> OnUnimplementedDirective {
 
         for command in self.subcommands.iter().chain(Some(self)).rev() {
             if let Some(ref condition) = command.condition
-                && !attr::eval_condition(
-                    condition,
-                    &tcx.sess.parse_sess,
-                    Some(tcx.features()),
-                    &mut |cfg| {
-                        let value = cfg.value.map(|v| {
-                            // `with_no_visible_paths` is also used when generating the options,
-                            // so we need to match it here.
-                            ty::print::with_no_visible_paths!(
-                                OnUnimplementedFormatString {
-                                    symbol: v,
-                                    span: cfg.span,
-                                    is_diagnostic_namespace_variant: false
-                                }
-                                .format(
-                                    tcx,
-                                    trait_ref,
-                                    &options_map
-                                )
-                            )
-                        });
-
-                        options.contains(&(cfg.name, value))
-                    },
-                )
+                && !attr::eval_condition(condition, &tcx.sess, Some(tcx.features()), &mut |cfg| {
+                    let value = cfg.value.map(|v| {
+                        // `with_no_visible_paths` is also used when generating the options,
+                        // so we need to match it here.
+                        ty::print::with_no_visible_paths!(
+                            OnUnimplementedFormatString {
+                                symbol: v,
+                                span: cfg.span,
+                                is_diagnostic_namespace_variant: false
+                            }
+                            .format(tcx, trait_ref, &options_map)
+                        )
+                    });
+
+                    options.contains(&(cfg.name, value))
+                })
             {
                 debug!("evaluate: skipping {:?} due to condition", command);
                 continue;
diff --git a/src/librustdoc/passes/check_custom_code_classes.rs b/src/librustdoc/passes/check_custom_code_classes.rs
index 73f71cc062b..451a44cd53a 100644
--- a/src/librustdoc/passes/check_custom_code_classes.rs
+++ b/src/librustdoc/passes/check_custom_code_classes.rs
@@ -65,9 +65,10 @@ pub(crate) fn look_for_custom_classes<'tcx>(cx: &DocContext<'tcx>, item: &Item)
 
     if !tests.custom_classes_found.is_empty() {
         let span = item.attr_span(cx.tcx);
-        let sess = &cx.tcx.sess.parse_sess;
-        let mut err =
-            sess.dcx.struct_span_warn(span, "custom classes in code blocks will change behaviour");
+        let sess = &cx.tcx.sess;
+        let mut err = sess
+            .dcx()
+            .struct_span_warn(span, "custom classes in code blocks will change behaviour");
         add_feature_diagnostics_for_issue(
             &mut err,
             sess,
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index b843227d187..dbff33dc1ec 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -1223,7 +1223,7 @@ impl LinkCollector<'_, '_> {
         )
         .unwrap_or_else(|| item.attr_span(self.cx.tcx));
         rustc_session::parse::feature_err(
-            &self.cx.tcx.sess.parse_sess,
+            &self.cx.tcx.sess,
             sym::intra_doc_pointers,
             span,
             "linking to associated items of raw pointers is experimental",