Importing rustc-1.71.0

Bug: 288268986
Test: ./build.py --lto=thin
Change-Id: Idffe995937cee91f5b480ce61ef8267475cec993
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index ff0f1f5..7277773 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -9,10 +9,9 @@
 use crate::imports::{Import, ImportKind};
 use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
 use crate::Namespace::{self, MacroNS, TypeNS, ValueNS};
+use crate::{errors, BindingKey, MacroData};
 use crate::{Determinacy, ExternPreludeEntry, Finalize, Module, ModuleKind, ModuleOrUniformRoot};
-use crate::{
-    MacroData, NameBinding, NameBindingKind, ParentScope, PathResult, PerNS, ResolutionError,
-};
+use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, PerNS, ResolutionError};
 use crate::{Resolver, ResolverArenas, Segment, ToNameBinding, VisResolutionError};
 
 use rustc_ast::visit::{self, AssocCtxt, Visitor};
@@ -70,7 +69,7 @@
         T: ToNameBinding<'a>,
     {
         let binding = def.to_name_binding(self.arenas);
-        let key = self.new_key(ident, ns);
+        let key = self.new_disambiguated_key(ident, ns);
         if let Err(old_binding) = self.try_define(parent, key, binding) {
             self.report_conflict(parent, ident, ns, old_binding, &binding);
         }
@@ -130,7 +129,7 @@
                     expn_id,
                     self.def_span(def_id),
                     // FIXME: Account for `#[no_implicit_prelude]` attributes.
-                    parent.map_or(false, |module| module.no_implicit_prelude),
+                    parent.is_some_and(|module| module.no_implicit_prelude),
                 ));
             }
         }
@@ -197,10 +196,7 @@
     }
 
     pub(crate) fn build_reduced_graph_external(&mut self, module: Module<'a>) {
-        // Query `module_children` is not used because hashing spans in its result is expensive.
-        let children =
-            Vec::from_iter(self.cstore().module_children_untracked(module.def_id(), self.tcx.sess));
-        for child in children {
+        for child in self.tcx.module_children(module.def_id()) {
             let parent_scope = ParentScope::module(module, self);
             BuildReducedGraphVisitor { r: self, parent_scope }
                 .build_reduced_graph_for_external_crate_res(child);
@@ -380,7 +376,7 @@
             ImportKind::Single { target, type_ns_only, .. } => {
                 self.r.per_ns(|this, ns| {
                     if !type_ns_only || ns == TypeNS {
-                        let key = this.new_key(target, ns);
+                        let key = BindingKey::new(target, ns);
                         let mut resolution = this.resolution(current_module, key).borrow_mut();
                         resolution.add_single_import(import);
                     }
@@ -526,11 +522,7 @@
                             ident.name = crate_name;
                         }
 
-                        self.r
-                            .tcx
-                            .sess
-                            .struct_span_err(item.span, "`$crate` may not be imported")
-                            .emit();
+                        self.r.tcx.sess.emit_err(errors::CrateImported { span: item.span });
                     }
                 }
 
@@ -881,6 +873,11 @@
                     let msg = "macro-expanded `extern crate` items cannot \
                                        shadow names passed with `--extern`";
                     self.r.tcx.sess.span_err(item.span, msg);
+                    // `return` is intended to discard this binding because it's an
+                    // unregistered ambiguity error which would result in a panic
+                    // caused by inconsistency `path_res`
+                    // more details: https://github.com/rust-lang/rust/pull/111761
+                    return;
                 }
             }
             let entry = self.r.extern_prelude.entry(ident.normalize_to_macros_2_0()).or_insert(
@@ -929,9 +926,15 @@
     }
 
     /// Builds the reduced graph for a single item in an external crate.
-    fn build_reduced_graph_for_external_crate_res(&mut self, child: ModChild) {
+    fn build_reduced_graph_for_external_crate_res(&mut self, child: &ModChild) {
         let parent = self.parent_scope.module;
-        let ModChild { ident, res, vis, span, .. } = child;
+        let ModChild { ident, res, vis, ref reexport_chain } = *child;
+        let span = self.r.def_span(
+            reexport_chain
+                .first()
+                .and_then(|reexport| reexport.id())
+                .unwrap_or_else(|| res.def_id()),
+        );
         let res = res.expect_non_local();
         let expansion = self.parent_scope.expansion;
         // Record primary definitions.
@@ -1001,7 +1004,7 @@
             let msg = format!("`{}` is already in scope", name);
             let note =
                 "macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560)";
-            self.r.tcx.sess.struct_span_err(span, &msg).note(note).emit();
+            self.r.tcx.sess.struct_span_err(span, msg).note(note).emit();
         }
     }
 
@@ -1025,11 +1028,7 @@
                         self.r
                             .tcx
                             .sess
-                            .struct_span_err(
-                                attr.span,
-                                "`#[macro_use]` is not supported on `extern crate self`",
-                            )
-                            .emit();
+                            .emit_err(errors::MacroUseExternCrateSelf { span: attr.span });
                     }
                 }
                 let ill_formed = |span| {
diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs
index ae3fd0e..dc35c8b 100644
--- a/compiler/rustc_resolve/src/check_unused.rs
+++ b/compiler/rustc_resolve/src/check_unused.rs
@@ -117,16 +117,11 @@
         match item.kind {
             ast::UseTreeKind::Simple(Some(ident)) => {
                 if ident.name == kw::Underscore
-                    && !self
-                        .r
-                        .import_res_map
-                        .get(&id)
-                        .map(|per_ns| {
-                            per_ns.iter().filter_map(|res| res.as_ref()).any(|res| {
-                                matches!(res, Res::Def(DefKind::Trait | DefKind::TraitAlias, _))
-                            })
+                    && !self.r.import_res_map.get(&id).is_some_and(|per_ns| {
+                        per_ns.iter().filter_map(|res| res.as_ref()).any(|res| {
+                            matches!(res, Res::Def(DefKind::Trait | DefKind::TraitAlias, _))
                         })
-                        .unwrap_or(false)
+                    })
                 {
                     self.unused_import(self.base_id).add(id);
                 }
@@ -418,7 +413,7 @@
                 UNUSED_IMPORTS,
                 unused.use_tree_id,
                 ms,
-                &msg,
+                msg,
                 BuiltinLintDiagnostics::UnusedImports(fix_msg.into(), fixes, test_module_span),
             );
         }
@@ -469,7 +464,7 @@
                 .r
                 .extern_prelude
                 .get(&extern_crate.ident)
-                .map_or(false, |entry| !entry.introduced_by_item)
+                .is_some_and(|entry| !entry.introduced_by_item)
             {
                 continue;
             }
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 0c9d306..8c6ac82 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -28,10 +28,10 @@
 use rustc_span::{BytePos, Span, SyntaxContext};
 use thin_vec::ThinVec;
 
-use crate::errors as errs;
 use crate::imports::{Import, ImportKind};
 use crate::late::{PatternSource, Rib};
 use crate::path_names_to_string;
+use crate::{errors as errs, BindingKey};
 use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingError, Finalize};
 use crate::{HasGenericParams, MacroRulesScope, Module, ModuleKind, ModuleOrUniformRoot};
 use crate::{LexicalScopeBinding, NameBinding, NameBindingKind, PrivacyError, VisResolutionError};
@@ -238,7 +238,7 @@
             },
         };
 
-        err.note(&format!(
+        err.note(format!(
             "`{}` must be defined only once in the {} namespace of this {}",
             name,
             ns.descr(),
@@ -663,15 +663,17 @@
                         Ident::with_dummy_span(name),
                         Namespace::ValueNS,
                         &parent_scope,
-                        &|res: Res| match res {
-                            Res::Def(
-                                DefKind::Ctor(CtorOf::Variant, CtorKind::Const)
-                                | DefKind::Ctor(CtorOf::Struct, CtorKind::Const)
-                                | DefKind::Const
-                                | DefKind::AssocConst,
-                                _,
-                            ) => true,
-                            _ => false,
+                        &|res: Res| {
+                            matches!(
+                                res,
+                                Res::Def(
+                                    DefKind::Ctor(CtorOf::Variant, CtorKind::Const)
+                                        | DefKind::Ctor(CtorOf::Struct, CtorKind::Const)
+                                        | DefKind::Const
+                                        | DefKind::AssocConst,
+                                    _,
+                                )
+                            )
                         },
                     );
 
@@ -681,7 +683,7 @@
                              making the path in the pattern qualified: `path::to::ModOrType::{}`",
                             name,
                         );
-                        err.span_help(span, &help_msg);
+                        err.span_help(span, help_msg);
                     }
                     show_candidates(
                         self.tcx,
@@ -781,10 +783,10 @@
 
                 if let Some((suggestions, msg, applicability)) = suggestion {
                     if suggestions.is_empty() {
-                        err.help(&msg);
+                        err.help(msg);
                         return err;
                     }
-                    err.multipart_suggestion(&msg, suggestions, applicability);
+                    err.multipart_suggestion(msg, suggestions, applicability);
                 }
 
                 err
@@ -862,18 +864,15 @@
             ResolutionError::ForwardDeclaredGenericParam => {
                 self.tcx.sess.create_err(errs::ForwardDeclaredGenericParam { span })
             }
-            ResolutionError::ParamInTyOfConstParam(name) => {
-                self.tcx.sess.create_err(errs::ParamInTyOfConstParam { span, name })
-            }
-            ResolutionError::ParamInNonTrivialAnonConst { name, is_type } => {
+            ResolutionError::ParamInTyOfConstParam { name, param_kind: is_type } => self
+                .tcx
+                .sess
+                .create_err(errs::ParamInTyOfConstParam { span, name, param_kind: is_type }),
+            ResolutionError::ParamInNonTrivialAnonConst { name, param_kind: is_type } => {
                 self.tcx.sess.create_err(errs::ParamInNonTrivialAnonConst {
                     span,
                     name,
-                    sub_is_type: if is_type {
-                        errs::ParamInNonTrivialAnonConstIsType::AType
-                    } else {
-                        errs::ParamInNonTrivialAnonConstIsType::NotAType { name }
-                    },
+                    param_kind: is_type,
                     help: self
                         .tcx
                         .sess
@@ -881,6 +880,10 @@
                         .then_some(errs::ParamInNonTrivialAnonConstHelp),
                 })
             }
+            ResolutionError::ParamInEnumDiscriminant { name, param_kind: is_type } => self
+                .tcx
+                .sess
+                .create_err(errs::ParamInEnumDiscriminant { span, name, param_kind: is_type }),
             ResolutionError::SelfInGenericParamDefault => {
                 self.tcx.sess.create_err(errs::SelfInGenericParamDefault { span })
             }
@@ -928,7 +931,7 @@
             } => {
                 let mut err = self.tcx.sess.struct_span_err_with_code(
                     span,
-                    &format!(
+                    format!(
                         "item `{}` is an associated {}, which doesn't match its trait `{}`",
                         name, kind, trait_path,
                     ),
@@ -945,6 +948,9 @@
             ResolutionError::InvalidAsmSym => {
                 self.tcx.sess.create_err(errs::InvalidAsmSym { span })
             }
+            ResolutionError::LowercaseSelf => {
+                self.tcx.sess.create_err(errs::LowercaseSelf { span })
+            }
         }
     }
 
@@ -1357,7 +1363,7 @@
 
         if macro_kind == MacroKind::Derive && (ident.name == sym::Send || ident.name == sym::Sync) {
             let msg = format!("unsafe traits like `{}` should be implemented explicitly", ident);
-            err.span_note(ident.span, &msg);
+            err.span_note(ident.span, msg);
             return;
         }
         if self.macro_names.contains(&ident.normalize_to_macros_2_0()) {
@@ -1417,7 +1423,7 @@
                     if !import.span.is_dummy() {
                         err.span_note(
                             import.span,
-                            &format!("`{}` is imported here, but it is {}", ident, desc),
+                            format!("`{}` is imported here, but it is {}", ident, desc),
                         );
                         // Silence the 'unused import' warning we might get,
                         // since this diagnostic already covers that import.
@@ -1425,7 +1431,7 @@
                         return;
                     }
                 }
-                err.note(&format!("`{}` is in scope, but it is {}", ident, desc));
+                err.note(format!("`{}` is in scope, but it is {}", ident, desc));
                 return;
             }
         }
@@ -1472,7 +1478,7 @@
 
             err.span_label(
                 self.tcx.sess.source_map().guess_head_span(def_span),
-                &format!(
+                format!(
                     "{}{} `{}` defined here",
                     prefix,
                     suggestion.res.descr(),
@@ -1490,7 +1496,7 @@
                 format!("maybe you meant this {}", suggestion.res.descr())
             }
         };
-        err.span_suggestion(span, &msg, suggestion.candidate, Applicability::MaybeIncorrect);
+        err.span_suggestion(span, msg, suggestion.candidate, Applicability::MaybeIncorrect);
         true
     }
 
@@ -1532,7 +1538,7 @@
 
         let mut err = struct_span_err!(self.tcx.sess, ident.span, E0659, "`{ident}` is ambiguous");
         err.span_label(ident.span, "ambiguous name");
-        err.note(&format!("ambiguous because of {}", kind.descr()));
+        err.note(format!("ambiguous because of {}", kind.descr()));
 
         let mut could_refer_to = |b: &NameBinding<'_>, misc: AmbiguityErrorMisc, also: &str| {
             let what = self.binding_description(b, ident, misc == AmbiguityErrorMisc::FromPrelude);
@@ -1560,10 +1566,10 @@
                 AmbiguityErrorMisc::FromPrelude | AmbiguityErrorMisc::None => {}
             }
 
-            err.span_note(b.span, &note_msg);
+            err.span_note(b.span, note_msg);
             for (i, help_msg) in help_msgs.iter().enumerate() {
                 let or = if i == 0 { "" } else { "or " };
-                err.help(&format!("{}{}", or, help_msg));
+                err.help(format!("{}{}", or, help_msg));
             }
         };
 
@@ -1606,7 +1612,7 @@
         let descr = get_descr(binding);
         let mut err =
             struct_span_err!(self.tcx.sess, ident.span, E0603, "{} `{}` is private", descr, ident);
-        err.span_label(ident.span, &format!("private {}", descr));
+        err.span_label(ident.span, format!("private {}", descr));
 
         let mut non_exhaustive = None;
         // If an ADT is foreign and marked as `non_exhaustive`, then that's
@@ -1621,7 +1627,7 @@
             err.span_label(span, "a constructor is private if any of the fields is private");
             if let Res::Def(_, d) = res && let Some(fields) = self.field_visibility_spans.get(&d) {
                 err.multipart_suggestion_verbose(
-                    &format!(
+                    format!(
                         "consider making the field{} publicly accessible",
                         pluralize!(fields.len())
                     ),
@@ -1674,7 +1680,7 @@
                     format!("cannot be constructed because it is `#[non_exhaustive]`"),
                 );
             }
-            err.span_note(note_span, &msg);
+            err.span_note(note_span, msg);
         }
 
         err.emit();
@@ -1826,8 +1832,18 @@
             }
             (msg, None)
         } else if ident.name == kw::SelfUpper {
-            ("`Self` is only available in impls, traits, and type definitions".to_string(), None)
-        } else if ident.name.as_str().chars().next().map_or(false, |c| c.is_ascii_uppercase()) {
+            // As mentioned above, `opt_ns` being `None` indicates a module path in import.
+            // We can use this to improve a confusing error for, e.g. `use Self::Variant` in an
+            // impl
+            if opt_ns.is_none() {
+                ("`Self` cannot be used in imports".to_string(), None)
+            } else {
+                (
+                    "`Self` is only available in impls, traits, and type definitions".to_string(),
+                    None,
+                )
+            }
+        } else if ident.name.as_str().chars().next().is_some_and(|c| c.is_ascii_uppercase()) {
             // Check whether the name refers to an item in the value namespace.
             let binding = if let Some(ribs) = ribs {
                 self.resolve_ident_in_lexical_scope(
@@ -1867,15 +1883,13 @@
                 Some(LexicalScopeBinding::Item(name_binding)) => Some(name_binding.span),
                 _ => None,
             };
-            let suggestion = if let Some(span) = match_span {
-                Some((
+            let suggestion = match_span.map(|span| {
+                (
                     vec![(span, String::from(""))],
                     format!("`{}` is defined here, but is not a type", ident),
                     Applicability::MaybeIncorrect,
-                ))
-            } else {
-                None
-            };
+                )
+            });
 
             (format!("use of undeclared type `{}`", ident), suggestion)
         } else {
@@ -2077,7 +2091,8 @@
         }
 
         let resolutions = self.resolutions(crate_module).borrow();
-        let resolution = resolutions.get(&self.new_key(ident, MacroNS))?;
+        let binding_key = BindingKey::new(ident, MacroNS);
+        let resolution = resolutions.get(&binding_key)?;
         let binding = resolution.borrow().binding()?;
         if let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() {
             let module_name = crate_module.kind.name().unwrap();
@@ -2150,7 +2165,7 @@
                 let is_definitely_crate = import
                     .module_path
                     .first()
-                    .map_or(false, |f| f.ident.name != kw::SelfLower && f.ident.name != kw::Super);
+                    .is_some_and(|f| f.ident.name != kw::SelfLower && f.ident.name != kw::Super);
 
                 // Add the import to the start, with a `{` if required.
                 let start_point = source_map.start_point(after_crate_name);
@@ -2444,7 +2459,7 @@
         };
 
         for note in accessible_path_strings.iter().flat_map(|cand| cand.3.as_ref()) {
-            err.note(note);
+            err.note(note.clone());
         }
 
         if let Some(span) = use_placement_span {
@@ -2452,7 +2467,7 @@
                 DiagnosticMode::Pattern => {
                     err.span_suggestions(
                         span,
-                        &msg,
+                        msg,
                         accessible_path_strings.into_iter().map(|a| a.0),
                         Applicability::MaybeIncorrect,
                     );
@@ -2471,7 +2486,7 @@
 
             err.span_suggestions_with_style(
                 span,
-                &msg,
+                msg,
                 accessible_path_strings.into_iter().map(|a| a.0),
                 Applicability::MaybeIncorrect,
                 SuggestionStyle::ShowAlways,
@@ -2481,7 +2496,7 @@
                 if sp.can_be_used_for_suggestions() {
                     err.span_suggestion_verbose(
                         sp,
-                        &format!("if you import `{}`, refer to it directly", last.ident),
+                        format!("if you import `{}`, refer to it directly", last.ident),
                         "",
                         Applicability::Unspecified,
                     );
@@ -2495,7 +2510,7 @@
                 msg.push_str(&candidate.0);
             }
 
-            err.help(&msg);
+            err.help(msg);
         }
     } else if !matches!(mode, DiagnosticMode::Import) {
         assert!(!inaccessible_path_strings.is_empty());
@@ -2520,9 +2535,9 @@
                 let span = tcx.sess.source_map().guess_head_span(span);
                 let mut multi_span = MultiSpan::from_span(span);
                 multi_span.push_span_label(span, "not accessible");
-                err.span_note(multi_span, &msg);
+                err.span_note(multi_span, msg);
             } else {
-                err.note(&msg);
+                err.note(msg);
             }
             if let Some(note) = (*note).as_deref() {
                 err.note(note);
@@ -2566,10 +2581,10 @@
             }
 
             for note in inaccessible_path_strings.iter().flat_map(|cand| cand.3.as_ref()) {
-                err.note(note);
+                err.note(note.clone());
             }
 
-            err.span_note(multi_span, &msg);
+            err.span_note(multi_span, msg);
         }
     }
 }
diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs
index bed579f..7393bdb 100644
--- a/compiler/rustc_resolve/src/effective_visibilities.rs
+++ b/compiler/rustc_resolve/src/effective_visibilities.rs
@@ -175,7 +175,7 @@
     /// to not update anything and we can skip it.
     ///
     /// We are checking this condition only if the correct value of private visibility is
-    /// cheaply available, otherwise it does't make sense performance-wise.
+    /// cheaply available, otherwise it doesn't make sense performance-wise.
     ///
     /// `None` is returned if the update can be skipped,
     /// and cheap private visibility is returned otherwise.
@@ -199,7 +199,7 @@
         let tcx = self.r.tcx;
         self.changed |= self.import_effective_visibilities.update(
             binding,
-            nominal_vis,
+            Some(nominal_vis),
             || cheap_private_vis.unwrap_or_else(|| self.r.private_vis_import(binding)),
             inherited_eff_vis,
             parent_id.level(),
@@ -213,7 +213,7 @@
         let tcx = self.r.tcx;
         self.changed |= self.def_effective_visibilities.update(
             def_id,
-            nominal_vis,
+            Some(nominal_vis),
             || cheap_private_vis.unwrap_or_else(|| self.r.private_vis_def(def_id)),
             inherited_eff_vis,
             parent_id.level(),
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index afa796c..2ab55f1 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -22,7 +22,7 @@
 
 #[derive(Diagnostic)]
 #[diag(resolve_crate_may_not_be_imported)]
-pub(crate) struct CrateMayNotBeImprted(#[primary_span] pub(crate) Span);
+pub(crate) struct CrateMayNotBeImported(#[primary_span] pub(crate) Span);
 
 #[derive(Diagnostic)]
 #[diag(resolve_crate_root_imports_must_be_named_explicitly)]
@@ -326,6 +326,18 @@
     #[label]
     pub(crate) span: Span,
     pub(crate) name: Symbol,
+    #[subdiagnostic]
+    pub(crate) param_kind: Option<ParamKindInTyOfConstParam>,
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum ParamKindInTyOfConstParam {
+    #[note(resolve_type_param_in_ty_of_const_param)]
+    Type,
+    #[note(resolve_const_param_in_ty_of_const_param)]
+    Const,
+    #[note(resolve_lifetime_param_in_ty_of_const_param)]
+    Lifetime,
 }
 
 #[derive(Diagnostic)]
@@ -344,7 +356,7 @@
     pub(crate) span: Span,
     pub(crate) name: Symbol,
     #[subdiagnostic]
-    pub(crate) sub_is_type: ParamInNonTrivialAnonConstIsType,
+    pub(crate) param_kind: ParamKindInNonTrivialAnonConst,
     #[subdiagnostic]
     pub(crate) help: Option<ParamInNonTrivialAnonConstHelp>,
 }
@@ -354,11 +366,13 @@
 pub(crate) struct ParamInNonTrivialAnonConstHelp;
 
 #[derive(Subdiagnostic)]
-pub(crate) enum ParamInNonTrivialAnonConstIsType {
-    #[note(resolve_param_in_non_trivial_anon_const_sub_type)]
-    AType,
-    #[help(resolve_param_in_non_trivial_anon_const_sub_non_type)]
-    NotAType { name: Symbol },
+pub(crate) enum ParamKindInNonTrivialAnonConst {
+    #[note(resolve_type_param_in_non_trivial_anon_const)]
+    Type,
+    #[help(resolve_const_param_in_non_trivial_anon_const)]
+    Const { name: Symbol },
+    #[note(resolve_lifetime_param_in_non_trivial_anon_const)]
+    Lifetime,
 }
 
 #[derive(Diagnostic)]
@@ -429,6 +443,14 @@
 }
 
 #[derive(Diagnostic)]
+#[diag(resolve_lowercase_self)]
+pub(crate) struct LowercaseSelf {
+    #[primary_span]
+    #[suggestion(code = "Self", applicability = "maybe-incorrect", style = "short")]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(resolve_trait_impl_duplicate, code = "E0201")]
 pub(crate) struct TraitImplDuplicate {
     #[primary_span]
@@ -508,3 +530,55 @@
 pub(crate) struct AddAsNonDerive<'a> {
     pub(crate) macro_path: &'a str,
 }
+
+#[derive(Diagnostic)]
+#[diag(resolve_proc_macro_same_crate)]
+pub(crate) struct ProcMacroSameCrate {
+    #[primary_span]
+    pub(crate) span: Span,
+    #[help]
+    pub(crate) is_test: bool,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_imported_crate)]
+pub(crate) struct CrateImported {
+    #[primary_span]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_macro_use_extern_crate_self)]
+pub(crate) struct MacroUseExternCrateSelf {
+    #[primary_span]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_accessible_unsure)]
+#[note]
+pub(crate) struct CfgAccessibleUnsure {
+    #[primary_span]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_param_in_enum_discriminant)]
+pub(crate) struct ParamInEnumDiscriminant {
+    #[primary_span]
+    #[label]
+    pub(crate) span: Span,
+    pub(crate) name: Symbol,
+    #[subdiagnostic]
+    pub(crate) param_kind: ParamKindInEnumDiscriminant,
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum ParamKindInEnumDiscriminant {
+    #[note(resolve_type_param_in_enum_discriminant)]
+    Type,
+    #[note(resolve_const_param_in_enum_discriminant)]
+    Const,
+    #[note(resolve_lifetime_param_in_enum_discriminant)]
+    Lifetime,
+}
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 5a56d7b..945c7ce 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -13,10 +13,12 @@
 
 use std::ptr;
 
+use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
 use crate::late::{
-    ConstantHasGenerics, ConstantItemKind, HasGenericParams, PathSource, Rib, RibKind,
+    ConstantHasGenerics, HasGenericParams, NoConstantGenericsReason, PathSource, Rib, RibKind,
 };
 use crate::macros::{sub_namespace_match, MacroRulesScope};
+use crate::BindingKey;
 use crate::{errors, AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy, Finalize};
 use crate::{Import, ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot};
 use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, PrivacyError, Res};
@@ -24,7 +26,6 @@
 
 use Determinacy::*;
 use Namespace::*;
-use RibKind::*;
 
 type Visibility = ty::Visibility<LocalDefId>;
 
@@ -324,8 +325,8 @@
             }
 
             module = match ribs[i].kind {
-                ModuleRibKind(module) => module,
-                MacroDefinition(def) if def == self.macro_def(ident.span.ctxt()) => {
+                RibKind::Module(module) => module,
+                RibKind::MacroDefinition(def) if def == self.macro_def(ident.span.ctxt()) => {
                     // If an invocation of this macro created `ident`, give up on `ident`
                     // and switch to `ident`'s source from the macro definition.
                     ident.span.remove_mark();
@@ -527,7 +528,7 @@
                                         PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
                                         lint_id,
                                         orig_ident.span,
-                                        &format!(
+                                        format!(
                                             "cannot find {} `{}` in this scope",
                                             ns.descr(),
                                             ident
@@ -865,7 +866,7 @@
             }
         };
 
-        let key = self.new_key(ident, ns);
+        let key = BindingKey::new(ident, ns);
         let resolution =
             self.resolution(module, key).try_borrow_mut().map_err(|_| (Determined, Weak::No))?; // This happens when there is a cycle of imports.
 
@@ -1084,7 +1085,7 @@
         let ribs = &all_ribs[rib_index + 1..];
 
         // An invalid forward use of a generic parameter from a previous default.
-        if let ForwardGenericParamBanRibKind = all_ribs[rib_index].kind {
+        if let RibKind::ForwardGenericParamBan = all_ribs[rib_index].kind {
             if let Some(span) = finalize {
                 let res_error = if rib_ident.name == kw::SelfUpper {
                     ResolutionError::SelfInGenericParamDefault
@@ -1104,14 +1105,14 @@
 
                 for rib in ribs {
                     match rib.kind {
-                        NormalRibKind
-                        | ClosureOrAsyncRibKind
-                        | ModuleRibKind(..)
-                        | MacroDefinition(..)
-                        | ForwardGenericParamBanRibKind => {
+                        RibKind::Normal
+                        | RibKind::ClosureOrAsync
+                        | RibKind::Module(..)
+                        | RibKind::MacroDefinition(..)
+                        | RibKind::ForwardGenericParamBan => {
                             // Nothing to do. Continue.
                         }
-                        ItemRibKind(_) | AssocItemRibKind => {
+                        RibKind::Item(_) | RibKind::AssocItem => {
                             // This was an attempt to access an upvar inside a
                             // named function item. This is not allowed, so we
                             // report an error.
@@ -1123,42 +1124,45 @@
                                 res_err = Some((span, CannotCaptureDynamicEnvironmentInFnItem));
                             }
                         }
-                        ConstantItemRibKind(_, item) => {
+                        RibKind::ConstantItem(_, item) => {
                             // Still doesn't deal with upvars
                             if let Some(span) = finalize {
-                                let (span, resolution_error) =
-                                    if let Some((ident, constant_item_kind)) = item {
-                                        let kind_str = match constant_item_kind {
-                                            ConstantItemKind::Const => "const",
-                                            ConstantItemKind::Static => "static",
-                                        };
-                                        (
-                                            span,
-                                            AttemptToUseNonConstantValueInConstant(
-                                                ident, "let", kind_str,
-                                            ),
-                                        )
-                                    } else {
-                                        (
-                                            rib_ident.span,
-                                            AttemptToUseNonConstantValueInConstant(
-                                                original_rib_ident_def,
-                                                "const",
-                                                "let",
-                                            ),
-                                        )
-                                    };
+                                let (span, resolution_error) = match item {
+                                    None if rib_ident.as_str() == "self" => (span, LowercaseSelf),
+                                    None => (
+                                        rib_ident.span,
+                                        AttemptToUseNonConstantValueInConstant(
+                                            original_rib_ident_def,
+                                            "const",
+                                            "let",
+                                        ),
+                                    ),
+                                    Some((ident, kind)) => (
+                                        span,
+                                        AttemptToUseNonConstantValueInConstant(
+                                            ident,
+                                            "let",
+                                            kind.as_str(),
+                                        ),
+                                    ),
+                                };
                                 self.report_error(span, resolution_error);
                             }
                             return Res::Err;
                         }
-                        ConstParamTyRibKind => {
+                        RibKind::ConstParamTy => {
                             if let Some(span) = finalize {
-                                self.report_error(span, ParamInTyOfConstParam(rib_ident.name));
+                                self.report_error(
+                                    span,
+                                    ParamInTyOfConstParam {
+                                        name: rib_ident.name,
+                                        param_kind: None,
+                                    },
+                                );
                             }
                             return Res::Err;
                         }
-                        InlineAsmSymRibKind => {
+                        RibKind::InlineAsmSym => {
                             if let Some(span) = finalize {
                                 self.report_error(span, InvalidAsmSym);
                             }
@@ -1174,23 +1178,19 @@
             Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {
                 for rib in ribs {
                     let has_generic_params: HasGenericParams = match rib.kind {
-                        NormalRibKind
-                        | ClosureOrAsyncRibKind
-                        | ModuleRibKind(..)
-                        | MacroDefinition(..)
-                        | InlineAsmSymRibKind
-                        | AssocItemRibKind
-                        | ForwardGenericParamBanRibKind => {
+                        RibKind::Normal
+                        | RibKind::ClosureOrAsync
+                        | RibKind::Module(..)
+                        | RibKind::MacroDefinition(..)
+                        | RibKind::InlineAsmSym
+                        | RibKind::AssocItem
+                        | RibKind::ForwardGenericParamBan => {
                             // Nothing to do. Continue.
                             continue;
                         }
 
-                        ConstantItemRibKind(trivial, _) => {
-                            let features = self.tcx.sess.features_untracked();
-                            // HACK(min_const_generics): We currently only allow `N` or `{ N }`.
-                            if !(trivial == ConstantHasGenerics::Yes
-                                || features.generic_const_exprs)
-                            {
+                        RibKind::ConstantItem(trivial, _) => {
+                            if let ConstantHasGenerics::No(cause) = trivial {
                                 // HACK(min_const_generics): If we encounter `Self` in an anonymous
                                 // constant we can't easily tell if it's generic at this stage, so
                                 // we instead remember this and then enforce the self type to be
@@ -1208,13 +1208,22 @@
                                     }
                                 } else {
                                     if let Some(span) = finalize {
-                                        self.report_error(
-                                            span,
-                                            ResolutionError::ParamInNonTrivialAnonConst {
-                                                name: rib_ident.name,
-                                                is_type: true,
-                                            },
-                                        );
+                                        let error = match cause {
+                                            NoConstantGenericsReason::IsEnumDiscriminant => {
+                                                ResolutionError::ParamInEnumDiscriminant {
+                                                    name: rib_ident.name,
+                                                    param_kind: ParamKindInEnumDiscriminant::Type,
+                                                }
+                                            }
+                                            NoConstantGenericsReason::NonTrivialConstArg => {
+                                                ResolutionError::ParamInNonTrivialAnonConst {
+                                                    name: rib_ident.name,
+                                                    param_kind:
+                                                        ParamKindInNonTrivialAnonConst::Type,
+                                                }
+                                            }
+                                        };
+                                        self.report_error(span, error);
                                         self.tcx.sess.delay_span_bug(span, CG_BUG_STR);
                                     }
 
@@ -1226,12 +1235,15 @@
                         }
 
                         // This was an attempt to use a type parameter outside its scope.
-                        ItemRibKind(has_generic_params) => has_generic_params,
-                        ConstParamTyRibKind => {
+                        RibKind::Item(has_generic_params) => has_generic_params,
+                        RibKind::ConstParamTy => {
                             if let Some(span) = finalize {
                                 self.report_error(
                                     span,
-                                    ResolutionError::ParamInTyOfConstParam(rib_ident.name),
+                                    ResolutionError::ParamInTyOfConstParam {
+                                        name: rib_ident.name,
+                                        param_kind: Some(errors::ParamKindInTyOfConstParam::Type),
+                                    },
                                 );
                             }
                             return Res::Err;
@@ -1253,29 +1265,34 @@
             Res::Def(DefKind::ConstParam, _) => {
                 for rib in ribs {
                     let has_generic_params = match rib.kind {
-                        NormalRibKind
-                        | ClosureOrAsyncRibKind
-                        | ModuleRibKind(..)
-                        | MacroDefinition(..)
-                        | InlineAsmSymRibKind
-                        | AssocItemRibKind
-                        | ForwardGenericParamBanRibKind => continue,
+                        RibKind::Normal
+                        | RibKind::ClosureOrAsync
+                        | RibKind::Module(..)
+                        | RibKind::MacroDefinition(..)
+                        | RibKind::InlineAsmSym
+                        | RibKind::AssocItem
+                        | RibKind::ForwardGenericParamBan => continue,
 
-                        ConstantItemRibKind(trivial, _) => {
-                            let features = self.tcx.sess.features_untracked();
-                            // HACK(min_const_generics): We currently only allow `N` or `{ N }`.
-                            if !(trivial == ConstantHasGenerics::Yes
-                                || features.generic_const_exprs)
-                            {
+                        RibKind::ConstantItem(trivial, _) => {
+                            if let ConstantHasGenerics::No(cause) = trivial {
                                 if let Some(span) = finalize {
-                                    self.report_error(
-                                        span,
-                                        ResolutionError::ParamInNonTrivialAnonConst {
-                                            name: rib_ident.name,
-                                            is_type: false,
-                                        },
-                                    );
-                                    self.tcx.sess.delay_span_bug(span, CG_BUG_STR);
+                                    let error = match cause {
+                                        NoConstantGenericsReason::IsEnumDiscriminant => {
+                                            ResolutionError::ParamInEnumDiscriminant {
+                                                name: rib_ident.name,
+                                                param_kind: ParamKindInEnumDiscriminant::Const,
+                                            }
+                                        }
+                                        NoConstantGenericsReason::NonTrivialConstArg => {
+                                            ResolutionError::ParamInNonTrivialAnonConst {
+                                                name: rib_ident.name,
+                                                param_kind: ParamKindInNonTrivialAnonConst::Const {
+                                                    name: rib_ident.name,
+                                                },
+                                            }
+                                        }
+                                    };
+                                    self.report_error(span, error);
                                 }
 
                                 return Res::Err;
@@ -1284,12 +1301,15 @@
                             continue;
                         }
 
-                        ItemRibKind(has_generic_params) => has_generic_params,
-                        ConstParamTyRibKind => {
+                        RibKind::Item(has_generic_params) => has_generic_params,
+                        RibKind::ConstParamTy => {
                             if let Some(span) = finalize {
                                 self.report_error(
                                     span,
-                                    ResolutionError::ParamInTyOfConstParam(rib_ident.name),
+                                    ResolutionError::ParamInTyOfConstParam {
+                                        name: rib_ident.name,
+                                        param_kind: Some(errors::ParamKindInTyOfConstParam::Const),
+                                    },
                                 );
                             }
                             return Res::Err;
@@ -1345,7 +1365,13 @@
         ribs: Option<&PerNS<Vec<Rib<'a>>>>,
         ignore_binding: Option<&'a NameBinding<'a>>,
     ) -> PathResult<'a> {
-        debug!("resolve_path(path={:?}, opt_ns={:?}, finalize={:?})", path, opt_ns, finalize);
+        debug!(
+            "resolve_path(path={:?}, opt_ns={:?}, finalize={:?}) path_len: {}",
+            path,
+            opt_ns,
+            finalize,
+            path.len()
+        );
 
         let mut module = None;
         let mut allow_super = true;
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 3c22d51..7c4c05d 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -405,17 +405,18 @@
         t
     }
 
-    // Define a dummy resolution containing a `Res::Err` as a placeholder for a failed resolution,
-    // also mark such failed imports as used to avoid duplicate diagnostics.
-    fn import_dummy_binding(&mut self, import: &'a Import<'a>) {
+    // Define a dummy resolution containing a `Res::Err` as a placeholder for a failed
+    // or indeterminate resolution, also mark such failed imports as used to avoid duplicate diagnostics.
+    fn import_dummy_binding(&mut self, import: &'a Import<'a>, is_indeterminate: bool) {
         if let ImportKind::Single { target, ref target_bindings, .. } = import.kind {
-            if target_bindings.iter().any(|binding| binding.get().is_some()) {
+            if !(is_indeterminate || target_bindings.iter().all(|binding| binding.get().is_none()))
+            {
                 return; // Has resolution, do not create the dummy binding
             }
             let dummy_binding = self.dummy_binding;
             let dummy_binding = self.import(dummy_binding, import);
             self.per_ns(|this, ns| {
-                let key = this.new_key(target, ns);
+                let key = BindingKey::new(target, ns);
                 let _ = this.try_define(import.parent_scope.module, key, dummy_binding);
             });
             self.record_use(target, dummy_binding, false);
@@ -474,7 +475,7 @@
 
             // If this import is unresolved then create a dummy import
             // resolution for it so that later resolve stages won't complain.
-            self.import_dummy_binding(import);
+            self.import_dummy_binding(import, is_indeterminate);
 
             if let Some(err) = unresolved_import_error {
                 if let ImportKind::Single { source, ref source_bindings, .. } = import.kind {
@@ -578,7 +579,7 @@
         let mut diag = struct_span_err!(self.tcx.sess, span, E0432, "{}", &msg);
 
         if let Some((_, UnresolvedImportError { note: Some(note), .. })) = errors.iter().last() {
-            diag.note(note);
+            diag.note(note.clone());
         }
 
         for (import, err) in errors.into_iter().take(MAX_LABEL_COUNT) {
@@ -588,10 +589,10 @@
 
             if let Some((suggestions, msg, applicability)) = err.suggestion {
                 if suggestions.is_empty() {
-                    diag.help(&msg);
+                    diag.help(msg);
                     continue;
                 }
-                diag.multipart_suggestion(&msg, suggestions, applicability);
+                diag.multipart_suggestion(msg, suggestions, applicability);
             }
 
             if let Some(candidates) = &err.candidates {
@@ -712,7 +713,7 @@
                                 .span_label(import.span, "cannot be imported directly")
                                 .emit();
                         }
-                        let key = this.new_key(target, ns);
+                        let key = BindingKey::new(target, ns);
                         this.update_resolution(parent, key, |_, resolution| {
                             resolution.single_imports.remove(&Interned::new_unchecked(import));
                         });
@@ -1063,7 +1064,7 @@
                     PUB_USE_OF_PRIVATE_EXTERN_CRATE,
                     import_id,
                     import.span,
-                    &msg,
+                    msg,
                 );
             } else {
                 let error_msg = if crate_private_reexport {
@@ -1084,7 +1085,7 @@
 
                     struct_span_err!(self.tcx.sess, import.span, E0365, "{}", error_msg)
                         .span_label(import.span, label_msg)
-                        .note(&format!("consider declaring type or module `{}` with `pub`", ident))
+                        .note(format!("consider declaring type or module `{}` with `pub`", ident))
                         .emit();
                 } else {
                     let mut err =
@@ -1102,7 +1103,7 @@
                         _ => {
                             err.span_note(
                                 import.span,
-                                &format!(
+                                format!(
                                     "consider marking `{ident}` as `pub` in the imported module"
                                 ),
                             );
@@ -1200,7 +1201,7 @@
                 UNUSED_IMPORTS,
                 id,
                 import.span,
-                &format!("the item `{}` is imported redundantly", ident),
+                format!("the item `{}` is imported redundantly", ident),
                 BuiltinLintDiagnostics::RedundantImport(redundant_spans, ident),
             );
         }
@@ -1261,14 +1262,11 @@
         *module.globs.borrow_mut() = Vec::new();
 
         if let Some(def_id) = module.opt_def_id() {
-            let mut non_reexports = Vec::new();
-            let mut reexports = Vec::new();
+            let mut children = Vec::new();
 
             module.for_each_child(self, |this, ident, _, binding| {
                 let res = binding.res().expect_non_local();
-                if !binding.is_import() {
-                    non_reexports.push(res.def_id().expect_local());
-                } else if res != def::Res::Err && !binding.is_ambiguity() {
+                if res != def::Res::Err && !binding.is_ambiguity() {
                     let mut reexport_chain = SmallVec::new();
                     let mut next_binding = binding;
                     while let NameBindingKind::Import { binding, import, .. } = next_binding.kind {
@@ -1276,23 +1274,13 @@
                         next_binding = binding;
                     }
 
-                    reexports.push(ModChild {
-                        ident,
-                        res,
-                        vis: binding.vis,
-                        span: binding.span,
-                        reexport_chain,
-                    });
+                    children.push(ModChild { ident, res, vis: binding.vis, reexport_chain });
                 }
             });
 
-            // Should be fine because this code is only called for local modules.
-            let def_id = def_id.expect_local();
-            if !non_reexports.is_empty() {
-                self.module_children_non_reexports.insert(def_id, non_reexports);
-            }
-            if !reexports.is_empty() {
-                self.module_children_reexports.insert(def_id, reexports);
+            if !children.is_empty() {
+                // Should be fine because this code is only called for local modules.
+                self.module_children.insert(def_id.expect_local(), children);
             }
         }
     }
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 90a2fa8..e061190 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -6,8 +6,7 @@
 //! If you wonder why there's no `early.rs`, that's because it's split into three files -
 //! `build_reduced_graph.rs`, `macros.rs` and `imports.rs`.
 
-use RibKind::*;
-
+use crate::BindingKey;
 use crate::{path_names_to_string, rustdoc, BindingError, Finalize, LexicalScopeBinding};
 use crate::{Module, ModuleOrUniformRoot, NameBinding, ParentScope, PathResult};
 use crate::{ResolutionError, Resolver, Segment, UseError};
@@ -18,7 +17,7 @@
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
 use rustc_errors::{Applicability, DiagnosticArgValue, DiagnosticId, IntoDiagnosticArg};
 use rustc_hir::def::Namespace::{self, *};
-use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, PartialRes, PerNS};
+use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS};
 use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
 use rustc_hir::{BindingAnnotation, PrimTy, TraitCandidate};
 use rustc_middle::middle::resolve_bound_vars::Set1;
@@ -68,6 +67,15 @@
     Yes,
 }
 
+/// Describes whether an `AnonConst` is a type level const arg or
+/// some other form of anon const (i.e. inline consts or enum discriminants)
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+enum AnonConstKind {
+    EnumDiscriminant,
+    InlineConst,
+    ConstArg(IsRepeatExpr),
+}
+
 impl PatternSource {
     fn descr(self) -> &'static str {
         match self {
@@ -107,7 +115,7 @@
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub(crate) enum ConstantHasGenerics {
     Yes,
-    No,
+    No(NoConstantGenericsReason),
 }
 
 impl ConstantHasGenerics {
@@ -116,12 +124,42 @@
     }
 }
 
+/// Reason for why an anon const is not allowed to reference generic parameters
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub(crate) enum NoConstantGenericsReason {
+    /// Const arguments are only allowed to use generic parameters when:
+    /// - `feature(generic_const_exprs)` is enabled
+    /// or
+    /// - the const argument is a sole const generic paramater, i.e. `foo::<{ N }>()`
+    ///
+    /// If neither of the above are true then this is used as the cause.
+    NonTrivialConstArg,
+    /// Enum discriminants are not allowed to reference generic parameters ever, this
+    /// is used when an anon const is in the following position:
+    ///
+    /// ```rust,compile_fail
+    /// enum Foo<const N: isize> {
+    ///     Variant = { N }, // this anon const is not allowed to use generics
+    /// }
+    /// ```
+    IsEnumDiscriminant,
+}
+
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub(crate) enum ConstantItemKind {
     Const,
     Static,
 }
 
+impl ConstantItemKind {
+    pub(crate) fn as_str(&self) -> &'static str {
+        match self {
+            Self::Const => "const",
+            Self::Static => "static",
+        }
+    }
+}
+
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
 enum RecordPartialRes {
     Yes,
@@ -133,28 +171,28 @@
 #[derive(Copy, Clone, Debug)]
 pub(crate) enum RibKind<'a> {
     /// No restriction needs to be applied.
-    NormalRibKind,
+    Normal,
 
     /// We passed through an impl or trait and are now in one of its
     /// methods or associated types. Allow references to ty params that impl or trait
     /// binds. Disallow any other upvars (including other ty params that are
     /// upvars).
-    AssocItemRibKind,
+    AssocItem,
 
     /// We passed through a closure. Disallow labels.
-    ClosureOrAsyncRibKind,
+    ClosureOrAsync,
 
     /// We passed through an item scope. Disallow upvars.
-    ItemRibKind(HasGenericParams),
+    Item(HasGenericParams),
 
     /// We're in a constant item. Can't refer to dynamic stuff.
     ///
     /// The item may reference generic parameters in trivial constant expressions.
     /// All other constants aren't allowed to use generic params at all.
-    ConstantItemRibKind(ConstantHasGenerics, Option<(Ident, ConstantItemKind)>),
+    ConstantItem(ConstantHasGenerics, Option<(Ident, ConstantItemKind)>),
 
     /// We passed through a module.
-    ModuleRibKind(Module<'a>),
+    Module(Module<'a>),
 
     /// We passed through a `macro_rules!` statement
     MacroDefinition(DefId),
@@ -162,15 +200,15 @@
     /// All bindings in this rib are generic parameters that can't be used
     /// from the default of a generic parameter because they're not declared
     /// before said generic parameter. Also see the `visit_generics` override.
-    ForwardGenericParamBanRibKind,
+    ForwardGenericParamBan,
 
     /// We are inside of the type of a const parameter. Can't refer to any
     /// parameters.
-    ConstParamTyRibKind,
+    ConstParamTy,
 
     /// We are inside a `sym` inline assembly operand. Can only refer to
     /// globals.
-    InlineAsmSymRibKind,
+    InlineAsmSym,
 }
 
 impl RibKind<'_> {
@@ -178,30 +216,30 @@
     /// variables.
     pub(crate) fn contains_params(&self) -> bool {
         match self {
-            NormalRibKind
-            | ClosureOrAsyncRibKind
-            | ConstantItemRibKind(..)
-            | ModuleRibKind(_)
-            | MacroDefinition(_)
-            | ConstParamTyRibKind
-            | InlineAsmSymRibKind => false,
-            AssocItemRibKind | ItemRibKind(_) | ForwardGenericParamBanRibKind => true,
+            RibKind::Normal
+            | RibKind::ClosureOrAsync
+            | RibKind::ConstantItem(..)
+            | RibKind::Module(_)
+            | RibKind::MacroDefinition(_)
+            | RibKind::ConstParamTy
+            | RibKind::InlineAsmSym => false,
+            RibKind::AssocItem | RibKind::Item(_) | RibKind::ForwardGenericParamBan => true,
         }
     }
 
     /// This rib forbids referring to labels defined in upwards ribs.
     fn is_label_barrier(self) -> bool {
         match self {
-            NormalRibKind | MacroDefinition(..) => false,
+            RibKind::Normal | RibKind::MacroDefinition(..) => false,
 
-            AssocItemRibKind
-            | ClosureOrAsyncRibKind
-            | ItemRibKind(..)
-            | ConstantItemRibKind(..)
-            | ModuleRibKind(..)
-            | ForwardGenericParamBanRibKind
-            | ConstParamTyRibKind
-            | InlineAsmSymRibKind => true,
+            RibKind::AssocItem
+            | RibKind::ClosureOrAsync
+            | RibKind::Item(..)
+            | RibKind::ConstantItem(..)
+            | RibKind::Module(..)
+            | RibKind::ForwardGenericParamBan
+            | RibKind::ConstParamTy
+            | RibKind::InlineAsmSym => true,
         }
     }
 }
@@ -275,15 +313,18 @@
     /// Signal we cannot find which should be the anonymous lifetime.
     ElisionFailure,
 
-    /// FIXME(const_generics): This patches over an ICE caused by non-'static lifetimes in const
-    /// generics. We are disallowing this until we can decide on how we want to handle non-'static
-    /// lifetimes in const generics. See issue #74052 for discussion.
-    ConstGeneric,
+    /// This rib forbids usage of generic parameters inside of const parameter types.
+    ///
+    /// While this is desirable to support eventually, it is difficult to do and so is
+    /// currently forbidden. See rust-lang/project-const-generics#28 for more info.
+    ConstParamTy,
 
-    /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
-    /// This function will emit an error if `generic_const_exprs` is not enabled, the body
-    /// identified by `body_id` is an anonymous constant and `lifetime_ref` is non-static.
-    AnonConst,
+    /// Usage of generic parameters is forbidden in various positions for anon consts:
+    /// - const arguments when `generic_const_exprs` is not enabled
+    /// - enum discriminant values
+    ///
+    /// This rib emits an error when a lifetime would resolve to a lifetime parameter.
+    ConcreteAnonConst(NoConstantGenericsReason),
 
     /// This rib acts as a barrier to forbid reference to lifetimes of a parent item.
     Item,
@@ -548,9 +589,6 @@
     /// they are used (in a `break` or `continue` statement)
     unused_labels: FxHashMap<NodeId, Span>,
 
-    /// Only used for better errors on `fn(): fn()`.
-    current_type_ascription: Vec<Span>,
-
     /// Only used for better errors on `let x = { foo: bar };`.
     /// In the case of a parse error with `let x = { foo: bar, };`, this isn't needed, it's only
     /// needed for cases where this parses as a correct type ascription.
@@ -653,13 +691,8 @@
         self.resolve_block(block);
         self.parent_scope.macro_rules = old_macro_rules;
     }
-    fn visit_anon_const(&mut self, constant: &'ast AnonConst) {
-        // We deal with repeat expressions explicitly in `resolve_expr`.
-        self.with_lifetime_rib(LifetimeRibKind::AnonConst, |this| {
-            this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| {
-                this.resolve_anon_const(constant, IsRepeatExpr::No);
-            })
-        })
+    fn visit_anon_const(&mut self, _constant: &'ast AnonConst) {
+        bug!("encountered anon const without a manual call to `resolve_anon_const`");
     }
     fn visit_expr(&mut self, expr: &'ast Expr) {
         self.resolve_expr(expr, None);
@@ -681,7 +714,7 @@
     fn visit_ty(&mut self, ty: &'ast Ty) {
         let prev = self.diagnostic_metadata.current_trait_object;
         let prev_ty = self.diagnostic_metadata.current_type_path;
-        match ty.kind {
+        match &ty.kind {
             TyKind::Ref(None, _) => {
                 // Elided lifetime in reference: we resolve as if there was some lifetime `'_` with
                 // NodeId `ty.id`.
@@ -690,7 +723,7 @@
                 self.resolve_elided_lifetime(ty.id, span);
                 visit::walk_ty(self, ty);
             }
-            TyKind::Path(ref qself, ref path) => {
+            TyKind::Path(qself, path) => {
                 self.diagnostic_metadata.current_type_path = Some(ty);
                 self.smart_resolve_path(ty.id, &qself, path, PathSource::Type);
 
@@ -705,7 +738,7 @@
                     let span = ty.span.shrink_to_lo().to(path.span.shrink_to_lo());
                     self.with_generic_param_rib(
                         &[],
-                        NormalRibKind,
+                        RibKind::Normal,
                         LifetimeRibKind::Generics {
                             binder: ty.id,
                             kind: LifetimeBinderKind::PolyTrait,
@@ -735,15 +768,15 @@
                 visit::walk_ty(self, ty);
                 self.lifetime_elision_candidates = candidates;
             }
-            TyKind::TraitObject(ref bounds, ..) => {
+            TyKind::TraitObject(bounds, ..) => {
                 self.diagnostic_metadata.current_trait_object = Some(&bounds[..]);
                 visit::walk_ty(self, ty)
             }
-            TyKind::BareFn(ref bare_fn) => {
+            TyKind::BareFn(bare_fn) => {
                 let span = ty.span.shrink_to_lo().to(bare_fn.decl_span.shrink_to_lo());
                 self.with_generic_param_rib(
                     &bare_fn.generic_params,
-                    NormalRibKind,
+                    RibKind::Normal,
                     LifetimeRibKind::Generics {
                         binder: ty.id,
                         kind: LifetimeBinderKind::BareFnType,
@@ -774,6 +807,13 @@
                     },
                 )
             }
+            TyKind::Array(element_ty, length) => {
+                self.visit_ty(element_ty);
+                self.resolve_anon_const(length, AnonConstKind::ConstArg(IsRepeatExpr::No));
+            }
+            TyKind::Typeof(ct) => {
+                self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::No))
+            }
             _ => visit::walk_ty(self, ty),
         }
         self.diagnostic_metadata.current_trait_object = prev;
@@ -783,7 +823,7 @@
         let span = tref.span.shrink_to_lo().to(tref.trait_ref.path.span.shrink_to_lo());
         self.with_generic_param_rib(
             &tref.bound_generic_params,
-            NormalRibKind,
+            RibKind::Normal,
             LifetimeRibKind::Generics {
                 binder: tref.trait_ref.ref_id,
                 kind: LifetimeBinderKind::PolyTrait,
@@ -807,7 +847,7 @@
             ForeignItemKind::TyAlias(box TyAlias { ref generics, .. }) => {
                 self.with_generic_param_rib(
                     &generics.params,
-                    ItemRibKind(HasGenericParams::Yes(generics.span)),
+                    RibKind::Item(HasGenericParams::Yes(generics.span)),
                     LifetimeRibKind::Generics {
                         binder: foreign_item.id,
                         kind: LifetimeBinderKind::Item,
@@ -819,7 +859,7 @@
             ForeignItemKind::Fn(box Fn { ref generics, .. }) => {
                 self.with_generic_param_rib(
                     &generics.params,
-                    ItemRibKind(HasGenericParams::Yes(generics.span)),
+                    RibKind::Item(HasGenericParams::Yes(generics.span)),
                     LifetimeRibKind::Generics {
                         binder: foreign_item.id,
                         kind: LifetimeBinderKind::Function,
@@ -859,13 +899,9 @@
                             sig.decl.inputs.iter().map(|Param { ty, .. }| (None, &**ty)),
                             &sig.decl.output,
                         );
-
-                        this.record_lifetime_params_for_async(
-                            fn_id,
-                            sig.header.asyncness.opt_return_id(),
-                        );
                     },
                 );
+                self.record_lifetime_params_for_async(fn_id, sig.header.asyncness.opt_return_id());
                 return;
             }
             FnKind::Fn(..) => {
@@ -877,9 +913,9 @@
         debug!("(resolving function) entering function");
 
         // Create a value rib for the function.
-        self.with_rib(ValueNS, ClosureOrAsyncRibKind, |this| {
+        self.with_rib(ValueNS, RibKind::ClosureOrAsync, |this| {
             // Create a label rib for the function.
-            this.with_label_rib(ClosureOrAsyncRibKind, |this| {
+            this.with_label_rib(RibKind::ClosureOrAsync, |this| {
                 match fn_kind {
                     FnKind::Fn(_, _, sig, _, generics, body) => {
                         this.visit_generics(generics);
@@ -1003,36 +1039,25 @@
                 // namespace first, and if that fails we try again in the value namespace. If
                 // resolution in the value namespace succeeds, we have an generic const argument on
                 // our hands.
-                if let TyKind::Path(ref qself, ref path) = ty.kind {
+                if let TyKind::Path(None, ref path) = ty.kind {
                     // We cannot disambiguate multi-segment paths right now as that requires type
                     // checking.
-                    if path.segments.len() == 1 && path.segments[0].args.is_none() {
+                    if path.is_potential_trivial_const_arg() {
                         let mut check_ns = |ns| {
                             self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns)
                                 .is_some()
                         };
                         if !check_ns(TypeNS) && check_ns(ValueNS) {
-                            // This must be equivalent to `visit_anon_const`, but we cannot call it
-                            // directly due to visitor lifetimes so we have to copy-paste some code.
-                            //
-                            // Note that we might not be inside of an repeat expression here,
-                            // but considering that `IsRepeatExpr` is only relevant for
-                            // non-trivial constants this is doesn't matter.
-                            self.with_constant_rib(
-                                IsRepeatExpr::No,
-                                ConstantHasGenerics::Yes,
-                                None,
+                            self.resolve_anon_const_manual(
+                                true,
+                                AnonConstKind::ConstArg(IsRepeatExpr::No),
                                 |this| {
                                     this.smart_resolve_path(
                                         ty.id,
-                                        qself,
+                                        &None,
                                         path,
                                         PathSource::Expr(None),
                                     );
-
-                                    if let Some(ref qself) = *qself {
-                                        this.visit_ty(&qself.ty);
-                                    }
                                     this.visit_path(path, ty.id);
                                 },
                             );
@@ -1046,7 +1071,9 @@
                 self.visit_ty(ty);
             }
             GenericArg::Lifetime(lt) => self.visit_lifetime(lt, visit::LifetimeCtxt::GenericArg),
-            GenericArg::Const(ct) => self.visit_anon_const(ct),
+            GenericArg::Const(ct) => {
+                self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::No))
+            }
         }
         self.diagnostic_metadata.currently_processing_generics = prev;
     }
@@ -1062,7 +1089,9 @@
         match constraint.kind {
             AssocConstraintKind::Equality { ref term } => match term {
                 Term::Ty(ty) => self.visit_ty(ty),
-                Term::Const(c) => self.visit_anon_const(c),
+                Term::Const(c) => {
+                    self.resolve_anon_const(c, AnonConstKind::ConstArg(IsRepeatExpr::No))
+                }
             },
             AssocConstraintKind::Bound { ref bounds } => {
                 walk_list!(self, visit_param_bound, bounds, BoundKind::Bound);
@@ -1079,7 +1108,7 @@
                     for rib in self.lifetime_ribs.iter().rev() {
                         match rib.kind {
                             // We are inside a `PolyTraitRef`. The lifetimes are
-                            // to be intoduced in that (maybe implicit) `for<>` binder.
+                            // to be introduced in that (maybe implicit) `for<>` binder.
                             LifetimeRibKind::Generics {
                                 binder,
                                 kind: LifetimeBinderKind::PolyTrait,
@@ -1111,8 +1140,8 @@
                             | LifetimeRibKind::AnonymousReportError
                             | LifetimeRibKind::Elided(_)
                             | LifetimeRibKind::ElisionFailure
-                            | LifetimeRibKind::AnonConst
-                            | LifetimeRibKind::ConstGeneric => {}
+                            | LifetimeRibKind::ConcreteAnonConst(_)
+                            | LifetimeRibKind::ConstParamTy => {}
                         }
                     }
                 }
@@ -1136,7 +1165,7 @@
                 let span = predicate_span.shrink_to_lo().to(bounded_ty.span.shrink_to_lo());
                 this.with_generic_param_rib(
                     &bound_generic_params,
-                    NormalRibKind,
+                    RibKind::Normal,
                     LifetimeRibKind::Generics {
                         binder: bounded_ty.id,
                         kind: LifetimeBinderKind::WhereBound,
@@ -1173,7 +1202,7 @@
                 InlineAsmOperand::Const { anon_const, .. } => {
                     // Although this is `DefKind::AnonConst`, it is allowed to reference outer
                     // generic parameters like an inline const.
-                    self.resolve_inline_const(anon_const);
+                    self.resolve_anon_const(anon_const, AnonConstKind::InlineConst);
                 }
                 InlineAsmOperand::Sym { sym } => self.visit_inline_asm_sym(sym),
             }
@@ -1182,9 +1211,9 @@
 
     fn visit_inline_asm_sym(&mut self, sym: &'ast InlineAsmSym) {
         // This is similar to the code for AnonConst.
-        self.with_rib(ValueNS, InlineAsmSymRibKind, |this| {
-            this.with_rib(TypeNS, InlineAsmSymRibKind, |this| {
-                this.with_label_rib(InlineAsmSymRibKind, |this| {
+        self.with_rib(ValueNS, RibKind::InlineAsmSym, |this| {
+            this.with_rib(TypeNS, RibKind::InlineAsmSym, |this| {
+                this.with_label_rib(RibKind::InlineAsmSym, |this| {
                     this.smart_resolve_path(sym.id, &sym.qself, &sym.path, PathSource::Expr(None));
                     visit::walk_inline_asm_sym(this, sym);
                 });
@@ -1197,6 +1226,10 @@
         visit::walk_variant(self, v)
     }
 
+    fn visit_variant_discr(&mut self, discr: &'ast AnonConst) {
+        self.resolve_anon_const(discr, AnonConstKind::EnumDiscriminant);
+    }
+
     fn visit_field_def(&mut self, f: &'ast FieldDef) {
         self.resolve_doc_links(&f.attrs, MaybeExported::Ok(f.id));
         visit::walk_field_def(self, f)
@@ -1209,7 +1242,7 @@
         // although it may be useful to track other components as well for diagnostics.
         let graph_root = resolver.graph_root;
         let parent_scope = ParentScope::module(graph_root, resolver);
-        let start_rib_kind = ModuleRibKind(graph_root);
+        let start_rib_kind = RibKind::Module(graph_root);
         LateResolutionVisitor {
             r: resolver,
             parent_scope,
@@ -1313,8 +1346,8 @@
         if let Some(module) = self.r.get_module(self.r.local_def_id(id).to_def_id()) {
             // Move down in the graph.
             let orig_module = replace(&mut self.parent_scope.module, module);
-            self.with_rib(ValueNS, ModuleRibKind(module), |this| {
-                this.with_rib(TypeNS, ModuleRibKind(module), |this| {
+            self.with_rib(ValueNS, RibKind::Module(module), |this| {
+                this.with_rib(TypeNS, RibKind::Module(module), |this| {
                     let ret = f(this);
                     this.parent_scope.module = orig_module;
                     ret
@@ -1331,8 +1364,8 @@
         // provide previous type parameters as they're built. We
         // put all the parameters on the ban list and then remove
         // them one by one as they are processed and become available.
-        let mut forward_ty_ban_rib = Rib::new(ForwardGenericParamBanRibKind);
-        let mut forward_const_ban_rib = Rib::new(ForwardGenericParamBanRibKind);
+        let mut forward_ty_ban_rib = Rib::new(RibKind::ForwardGenericParamBan);
+        let mut forward_const_ban_rib = Rib::new(RibKind::ForwardGenericParamBan);
         for param in params.iter() {
             match param.kind {
                 GenericParamKind::Type { .. } => {
@@ -1393,9 +1426,9 @@
                         // Const parameters can't have param bounds.
                         assert!(param.bounds.is_empty());
 
-                        this.ribs[TypeNS].push(Rib::new(ConstParamTyRibKind));
-                        this.ribs[ValueNS].push(Rib::new(ConstParamTyRibKind));
-                        this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| {
+                        this.ribs[TypeNS].push(Rib::new(RibKind::ConstParamTy));
+                        this.ribs[ValueNS].push(Rib::new(RibKind::ConstParamTy));
+                        this.with_lifetime_rib(LifetimeRibKind::ConstParamTy, |this| {
                             this.visit_ty(ty)
                         });
                         this.ribs[TypeNS].pop().unwrap();
@@ -1404,9 +1437,10 @@
                         if let Some(ref expr) = default {
                             this.ribs[TypeNS].push(forward_ty_ban_rib);
                             this.ribs[ValueNS].push(forward_const_ban_rib);
-                            this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| {
-                                this.resolve_anon_const(expr, IsRepeatExpr::No)
-                            });
+                            this.resolve_anon_const(
+                                expr,
+                                AnonConstKind::ConstArg(IsRepeatExpr::No),
+                            );
                             forward_const_ban_rib = this.ribs[ValueNS].pop().unwrap();
                             forward_ty_ban_rib = this.ribs[TypeNS].pop().unwrap();
                         }
@@ -1458,7 +1492,7 @@
             if let Some(&(_, res)) = rib.bindings.get(&normalized_ident) {
                 self.record_lifetime_res(lifetime.id, res, LifetimeElisionCandidate::Named);
 
-                if let LifetimeRes::Param { param, .. } = res {
+                if let LifetimeRes::Param { param, binder } = res {
                     match self.lifetime_uses.entry(param) {
                         Entry::Vacant(v) => {
                             debug!("First use of {:?} at {:?}", res, ident.span);
@@ -1472,10 +1506,16 @@
                                     LifetimeRibKind::Item
                                     | LifetimeRibKind::AnonymousReportError
                                     | LifetimeRibKind::ElisionFailure => Some(LifetimeUseSet::Many),
-                                    // An anonymous lifetime is legal here, go ahead.
-                                    LifetimeRibKind::AnonymousCreateParameter { .. } => {
-                                        Some(LifetimeUseSet::One { use_span: ident.span, use_ctxt })
-                                    }
+                                    // An anonymous lifetime is legal here, and bound to the right
+                                    // place, go ahead.
+                                    LifetimeRibKind::AnonymousCreateParameter {
+                                        binder: anon_binder,
+                                        ..
+                                    } => Some(if binder == anon_binder {
+                                        LifetimeUseSet::One { use_span: ident.span, use_ctxt }
+                                    } else {
+                                        LifetimeUseSet::Many
+                                    }),
                                     // Only report if eliding the lifetime would have the same
                                     // semantics.
                                     LifetimeRibKind::Elided(r) => Some(if res == r {
@@ -1484,8 +1524,8 @@
                                         LifetimeUseSet::Many
                                     }),
                                     LifetimeRibKind::Generics { .. }
-                                    | LifetimeRibKind::ConstGeneric => None,
-                                    LifetimeRibKind::AnonConst => {
+                                    | LifetimeRibKind::ConstParamTy => None,
+                                    LifetimeRibKind::ConcreteAnonConst(_) => {
                                         span_bug!(ident.span, "unexpected rib kind: {:?}", rib.kind)
                                     }
                                 })
@@ -1504,8 +1544,8 @@
 
             match rib.kind {
                 LifetimeRibKind::Item => break,
-                LifetimeRibKind::ConstGeneric => {
-                    self.emit_non_static_lt_in_const_generic_error(lifetime);
+                LifetimeRibKind::ConstParamTy => {
+                    self.emit_non_static_lt_in_const_param_ty_error(lifetime);
                     self.record_lifetime_res(
                         lifetime.id,
                         LifetimeRes::Error,
@@ -1513,8 +1553,8 @@
                     );
                     return;
                 }
-                LifetimeRibKind::AnonConst => {
-                    self.maybe_emit_forbidden_non_static_lifetime_error(lifetime);
+                LifetimeRibKind::ConcreteAnonConst(cause) => {
+                    self.emit_forbidden_non_static_lifetime_error(cause, lifetime);
                     self.record_lifetime_res(
                         lifetime.id,
                         LifetimeRes::Error,
@@ -1613,9 +1653,9 @@
                     return;
                 }
                 LifetimeRibKind::Item => break,
-                LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstGeneric => {}
-                LifetimeRibKind::AnonConst => {
-                    // There is always an `Elided(LifetimeRes::Static)` inside an `AnonConst`.
+                LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstParamTy => {}
+                LifetimeRibKind::ConcreteAnonConst(_) => {
+                    // There is always an `Elided(LifetimeRes::Infer)` inside an `AnonConst`.
                     span_bug!(lifetime.ident.span, "unexpected rib kind: {:?}", rib.kind)
                 }
             }
@@ -1835,9 +1875,9 @@
                         self.report_missing_lifetime_specifiers(vec![missing_lifetime], None);
                         break;
                     }
-                    LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstGeneric => {}
-                    LifetimeRibKind::AnonConst => {
-                        // There is always an `Elided(LifetimeRes::Static)` inside an `AnonConst`.
+                    LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstParamTy => {}
+                    LifetimeRibKind::ConcreteAnonConst(_) => {
+                        // There is always an `Elided(LifetimeRes::Infer)` inside an `AnonConst`.
                         span_bug!(elided_lifetime_span, "unexpected rib kind: {:?}", rib.kind)
                     }
                 }
@@ -2079,6 +2119,10 @@
                 }
                 visit::walk_ty(self, ty)
             }
+
+            // A type may have an expression as a const generic argument.
+            // We do not want to recurse into those.
+            fn visit_expr(&mut self, _: &'a Expr) {}
         }
 
         let impl_self = self
@@ -2116,7 +2160,7 @@
         for i in (0..self.label_ribs.len()).rev() {
             let rib = &self.label_ribs[i];
 
-            if let MacroDefinition(def) = rib.kind {
+            if let RibKind::MacroDefinition(def) = rib.kind {
                 // If an invocation of this macro created `ident`, give up on `ident`
                 // and switch to `ident`'s source from the macro definition.
                 if def == self.r.macro_def(label.span.ctxt()) {
@@ -2164,7 +2208,7 @@
         self.with_current_self_item(item, |this| {
             this.with_generic_param_rib(
                 &generics.params,
-                ItemRibKind(HasGenericParams::Yes(generics.span)),
+                RibKind::Item(HasGenericParams::Yes(generics.span)),
                 LifetimeRibKind::Generics {
                     binder: item.id,
                     kind: LifetimeBinderKind::Item,
@@ -2205,7 +2249,7 @@
                     this.r
                         .tcx
                         .sess
-                        .span_err(ident.span, &format!("imports cannot refer to {}", what));
+                        .span_err(ident.span, format!("imports cannot refer to {}", what));
                 }
             };
 
@@ -2245,7 +2289,7 @@
             ItemKind::TyAlias(box TyAlias { ref generics, .. }) => {
                 self.with_generic_param_rib(
                     &generics.params,
-                    ItemRibKind(HasGenericParams::Yes(generics.span)),
+                    RibKind::Item(HasGenericParams::Yes(generics.span)),
                     LifetimeRibKind::Generics {
                         binder: item.id,
                         kind: LifetimeBinderKind::Item,
@@ -2258,7 +2302,7 @@
             ItemKind::Fn(box Fn { ref generics, .. }) => {
                 self.with_generic_param_rib(
                     &generics.params,
-                    ItemRibKind(HasGenericParams::Yes(generics.span)),
+                    RibKind::Item(HasGenericParams::Yes(generics.span)),
                     LifetimeRibKind::Generics {
                         binder: item.id,
                         kind: LifetimeBinderKind::Function,
@@ -2297,7 +2341,7 @@
                 // Create a new rib for the trait-wide type parameters.
                 self.with_generic_param_rib(
                     &generics.params,
-                    ItemRibKind(HasGenericParams::Yes(generics.span)),
+                    RibKind::Item(HasGenericParams::Yes(generics.span)),
                     LifetimeRibKind::Generics {
                         binder: item.id,
                         kind: LifetimeBinderKind::Item,
@@ -2318,7 +2362,7 @@
                 // Create a new rib for the trait-wide type parameters.
                 self.with_generic_param_rib(
                     &generics.params,
-                    ItemRibKind(HasGenericParams::Yes(generics.span)),
+                    RibKind::Item(HasGenericParams::Yes(generics.span)),
                     LifetimeRibKind::Generics {
                         binder: item.id,
                         kind: LifetimeBinderKind::Item,
@@ -2421,11 +2465,11 @@
         let mut seen_lifetimes = FxHashSet::default();
 
         // We also can't shadow bindings from the parent item
-        if let AssocItemRibKind = kind {
+        if let RibKind::AssocItem = kind {
             let mut add_bindings_for_ns = |ns| {
                 let parent_rib = self.ribs[ns]
                     .iter()
-                    .rfind(|r| matches!(r.kind, ItemRibKind(_)))
+                    .rfind(|r| matches!(r.kind, RibKind::Item(_)))
                     .expect("associated item outside of an item");
                 seen_bindings.extend(parent_rib.bindings.keys().map(|ident| (*ident, ident.span)));
             };
@@ -2514,8 +2558,8 @@
             };
 
             let res = match kind {
-                ItemRibKind(..) | AssocItemRibKind => Res::Def(def_kind, def_id.to_def_id()),
-                NormalRibKind => {
+                RibKind::Item(..) | RibKind::AssocItem => Res::Def(def_kind, def_id.to_def_id()),
+                RibKind::Normal => {
                     if self.r.tcx.sess.features_untracked().non_lifetime_binders {
                         Res::Def(def_kind, def_id.to_def_id())
                     } else {
@@ -2561,11 +2605,11 @@
     }
 
     fn with_static_rib(&mut self, f: impl FnOnce(&mut Self)) {
-        let kind = ItemRibKind(HasGenericParams::No);
+        let kind = RibKind::Item(HasGenericParams::No);
         self.with_rib(ValueNS, kind, |this| this.with_rib(TypeNS, kind, f))
     }
 
-    // HACK(min_const_generics,const_evaluatable_unchecked): We
+    // HACK(min_const_generics, generic_const_exprs): We
     // want to keep allowing `[0; std::mem::size_of::<*mut T>()]`
     // with a future compat lint for now. We do this by adding an
     // additional special case for repeat expressions.
@@ -2581,18 +2625,26 @@
         item: Option<(Ident, ConstantItemKind)>,
         f: impl FnOnce(&mut Self),
     ) {
-        self.with_rib(ValueNS, ConstantItemRibKind(may_use_generics, item), |this| {
-            this.with_rib(
-                TypeNS,
-                ConstantItemRibKind(
-                    may_use_generics.force_yes_if(is_repeat == IsRepeatExpr::Yes),
-                    item,
-                ),
-                |this| {
-                    this.with_label_rib(ConstantItemRibKind(may_use_generics, item), f);
-                },
-            )
-        });
+        let f = |this: &mut Self| {
+            this.with_rib(ValueNS, RibKind::ConstantItem(may_use_generics, item), |this| {
+                this.with_rib(
+                    TypeNS,
+                    RibKind::ConstantItem(
+                        may_use_generics.force_yes_if(is_repeat == IsRepeatExpr::Yes),
+                        item,
+                    ),
+                    |this| {
+                        this.with_label_rib(RibKind::ConstantItem(may_use_generics, item), f);
+                    },
+                )
+            })
+        };
+
+        if let ConstantHasGenerics::No(cause) = may_use_generics {
+            self.with_lifetime_rib(LifetimeRibKind::ConcreteAnonConst(cause), f)
+        } else {
+            f(self)
+        }
     }
 
     fn with_current_self_type<T>(&mut self, self_type: &Ty, f: impl FnOnce(&mut Self) -> T) -> T {
@@ -2621,7 +2673,7 @@
             |this: &mut Self, generics: &Generics, kind, item: &'ast AssocItem| {
                 this.with_generic_param_rib(
                     &generics.params,
-                    AssocItemRibKind,
+                    RibKind::AssocItem,
                     LifetimeRibKind::Generics { binder: item.id, span: generics.span, kind },
                     |this| visit::walk_assoc_item(this, item, AssocCtxt::Trait),
                 );
@@ -2702,7 +2754,7 @@
     }
 
     fn with_self_rib_ns(&mut self, ns: Namespace, self_res: Res, f: impl FnOnce(&mut Self)) {
-        let mut self_type_rib = Rib::new(NormalRibKind);
+        let mut self_type_rib = Rib::new(RibKind::Normal);
 
         // Plain insert (no renaming, since types are not currently hygienic)
         self_type_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), self_res);
@@ -2728,7 +2780,7 @@
         // If applicable, create a rib for the type parameters.
         self.with_generic_param_rib(
             &generics.params,
-            ItemRibKind(HasGenericParams::Yes(generics.span)),
+            RibKind::Item(HasGenericParams::Yes(generics.span)),
             LifetimeRibKind::Generics {
                 span: generics.span,
                 binder: item_id,
@@ -2842,7 +2894,7 @@
                 // We also need a new scope for the impl item type parameters.
                 self.with_generic_param_rib(
                     &generics.params,
-                    AssocItemRibKind,
+                    RibKind::AssocItem,
                     LifetimeRibKind::Generics {
                         binder: item.id,
                         span: generics.span,
@@ -2870,7 +2922,7 @@
                 // We also need a new scope for the impl item type parameters.
                 self.with_generic_param_rib(
                     &generics.params,
-                    AssocItemRibKind,
+                    RibKind::AssocItem,
                     LifetimeRibKind::Generics {
                         binder: item.id,
                         span: generics.span,
@@ -2916,7 +2968,7 @@
         // If there is a TraitRef in scope for an impl, then the method must be in the trait.
         let Some((module, _)) = &self.current_trait_ref else { return; };
         ident.span.normalize_to_macros_2_0_and_adjust(module.expansion);
-        let key = self.r.new_key(ident, ns);
+        let key = BindingKey::new(ident, ns);
         let mut binding = self.r.resolution(module, key).try_borrow().ok().and_then(|r| r.binding);
         debug!(?binding);
         if binding.is_none() {
@@ -2927,7 +2979,7 @@
                 TypeNS => ValueNS,
                 _ => ns,
             };
-            let key = self.r.new_key(ident, ns);
+            let key = BindingKey::new(ident, ns);
             binding = self.r.resolution(module, key).try_borrow().ok().and_then(|r| r.binding);
             debug!(?binding);
         }
@@ -3142,7 +3194,7 @@
     }
 
     fn resolve_arm(&mut self, arm: &'ast Arm) {
-        self.with_rib(ValueNS, NormalRibKind, |this| {
+        self.with_rib(ValueNS, RibKind::Normal, |this| {
             this.resolve_pattern_top(&arm.pat, PatternSource::Match);
             walk_list!(this, visit_expr, &arm.guard);
             this.visit_expr(&arm.body);
@@ -3492,10 +3544,6 @@
         //
         // Similar thing, for types, happens in `report_errors` above.
         let report_errors_for_call = |this: &mut Self, parent_err: Spanned<ResolutionError<'a>>| {
-            if !source.is_call() {
-                return Some(parent_err);
-            }
-
             // Before we start looking for candidates, we have to get our hands
             // on the type user is trying to perform invocation on; basically:
             // we're transforming `HashMap::new` into just `HashMap`.
@@ -3803,7 +3851,7 @@
             // use std::u8; // bring module u8 in scope
             // fn f() -> u8 { // OK, resolves to primitive u8, not to std::u8
             //     u8::max_value() // OK, resolves to associated function <u8>::max_value,
-            //                     // not to non-existent std::u8::max_value
+            //                     // not to nonexistent std::u8::max_value
             // }
             //
             // Such behavior is required for backward compatibility.
@@ -3864,7 +3912,7 @@
                 diagnostics::signal_label_shadowing(self.r.tcx.sess, orig_span, label.ident)
             }
 
-            self.with_label_rib(NormalRibKind, |this| {
+            self.with_label_rib(RibKind::Normal, |this| {
                 let ident = label.ident.normalize_to_macro_rules();
                 this.label_ribs.last_mut().unwrap().bindings.insert(ident, id);
                 f(this);
@@ -3887,11 +3935,11 @@
         let mut num_macro_definition_ribs = 0;
         if let Some(anonymous_module) = anonymous_module {
             debug!("(resolving block) found anonymous module, moving down");
-            self.ribs[ValueNS].push(Rib::new(ModuleRibKind(anonymous_module)));
-            self.ribs[TypeNS].push(Rib::new(ModuleRibKind(anonymous_module)));
+            self.ribs[ValueNS].push(Rib::new(RibKind::Module(anonymous_module)));
+            self.ribs[TypeNS].push(Rib::new(RibKind::Module(anonymous_module)));
             self.parent_scope.module = anonymous_module;
         } else {
-            self.ribs[ValueNS].push(Rib::new(NormalRibKind));
+            self.ribs[ValueNS].push(Rib::new(RibKind::Normal));
         }
 
         let prev = self.diagnostic_metadata.current_block_could_be_bare_struct_literal.take();
@@ -3908,8 +3956,8 @@
                 && let ItemKind::MacroDef(..) = item.kind {
                 num_macro_definition_ribs += 1;
                 let res = self.r.local_def_id(item.id).to_def_id();
-                self.ribs[ValueNS].push(Rib::new(MacroDefinition(res)));
-                self.label_ribs.push(Rib::new(MacroDefinition(res)));
+                self.ribs[ValueNS].push(Rib::new(RibKind::MacroDefinition(res)));
+                self.label_ribs.push(Rib::new(RibKind::MacroDefinition(res)));
             }
 
             self.visit_stmt(stmt);
@@ -3929,24 +3977,54 @@
         debug!("(resolving block) leaving block");
     }
 
-    fn resolve_anon_const(&mut self, constant: &'ast AnonConst, is_repeat: IsRepeatExpr) {
-        debug!("resolve_anon_const {:?} is_repeat: {:?}", constant, is_repeat);
-        self.with_constant_rib(
-            is_repeat,
-            if constant.value.is_potential_trivial_const_param() {
-                ConstantHasGenerics::Yes
-            } else {
-                ConstantHasGenerics::No
-            },
-            None,
-            |this| visit::walk_anon_const(this, constant),
+    fn resolve_anon_const(&mut self, constant: &'ast AnonConst, anon_const_kind: AnonConstKind) {
+        debug!(
+            "resolve_anon_const(constant: {:?}, anon_const_kind: {:?})",
+            constant, anon_const_kind
         );
+
+        self.resolve_anon_const_manual(
+            constant.value.is_potential_trivial_const_arg(),
+            anon_const_kind,
+            |this| this.resolve_expr(&constant.value, None),
+        )
     }
 
-    fn resolve_inline_const(&mut self, constant: &'ast AnonConst) {
-        debug!("resolve_anon_const {constant:?}");
-        self.with_constant_rib(IsRepeatExpr::No, ConstantHasGenerics::Yes, None, |this| {
-            visit::walk_anon_const(this, constant)
+    /// There are a few places that we need to resolve an anon const but we did not parse an
+    /// anon const so cannot provide an `&'ast AnonConst`. Right now this is just unbraced
+    /// const arguments that were parsed as type arguments, and `legact_const_generics` which
+    /// parse as normal function argument expressions. To avoid duplicating the code for resolving
+    /// an anon const we have this function which lets the caller manually call `resolve_expr` or
+    /// `smart_resolve_path`.
+    fn resolve_anon_const_manual(
+        &mut self,
+        is_trivial_const_arg: bool,
+        anon_const_kind: AnonConstKind,
+        resolve_expr: impl FnOnce(&mut Self),
+    ) {
+        let is_repeat_expr = match anon_const_kind {
+            AnonConstKind::ConstArg(is_repeat_expr) => is_repeat_expr,
+            _ => IsRepeatExpr::No,
+        };
+
+        let may_use_generics = match anon_const_kind {
+            AnonConstKind::EnumDiscriminant => {
+                ConstantHasGenerics::No(NoConstantGenericsReason::IsEnumDiscriminant)
+            }
+            AnonConstKind::InlineConst => ConstantHasGenerics::Yes,
+            AnonConstKind::ConstArg(_) => {
+                if self.r.tcx.features().generic_const_exprs || is_trivial_const_arg {
+                    ConstantHasGenerics::Yes
+                } else {
+                    ConstantHasGenerics::No(NoConstantGenericsReason::NonTrivialConstArg)
+                }
+            }
+        };
+
+        self.with_constant_rib(is_repeat_expr, may_use_generics, None, |this| {
+            this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| {
+                resolve_expr(this);
+            });
         });
     }
 
@@ -3996,7 +4074,7 @@
             }
 
             ExprKind::If(ref cond, ref then, ref opt_else) => {
-                self.with_rib(ValueNS, NormalRibKind, |this| {
+                self.with_rib(ValueNS, RibKind::Normal, |this| {
                     let old = this.diagnostic_metadata.in_if_condition.replace(cond);
                     this.visit_expr(cond);
                     this.diagnostic_metadata.in_if_condition = old;
@@ -4013,7 +4091,7 @@
 
             ExprKind::While(ref cond, ref block, label) => {
                 self.with_resolved_label(label, expr.id, |this| {
-                    this.with_rib(ValueNS, NormalRibKind, |this| {
+                    this.with_rib(ValueNS, RibKind::Normal, |this| {
                         let old = this.diagnostic_metadata.in_if_condition.replace(cond);
                         this.visit_expr(cond);
                         this.diagnostic_metadata.in_if_condition = old;
@@ -4024,7 +4102,7 @@
 
             ExprKind::ForLoop(ref pat, ref iter_expr, ref block, label) => {
                 self.visit_expr(iter_expr);
-                self.with_rib(ValueNS, NormalRibKind, |this| {
+                self.with_rib(ValueNS, RibKind::Normal, |this| {
                     this.resolve_pattern_top(pat, PatternSource::For);
                     this.resolve_labeled_block(label, expr.id, block);
                 });
@@ -4051,34 +4129,18 @@
                     // Constant arguments need to be treated as AnonConst since
                     // that is how they will be later lowered to HIR.
                     if const_args.contains(&idx) {
-                        self.with_constant_rib(
-                            IsRepeatExpr::No,
-                            if argument.is_potential_trivial_const_param() {
-                                ConstantHasGenerics::Yes
-                            } else {
-                                ConstantHasGenerics::No
-                            },
-                            None,
-                            |this| {
-                                this.resolve_expr(argument, None);
-                            },
+                        self.resolve_anon_const_manual(
+                            argument.is_potential_trivial_const_arg(),
+                            AnonConstKind::ConstArg(IsRepeatExpr::No),
+                            |this| this.resolve_expr(argument, None),
                         );
                     } else {
                         self.resolve_expr(argument, None);
                     }
                 }
             }
-            ExprKind::Type(ref type_expr, ref ty) => {
-                // `ParseSess::type_ascription_path_suggestions` keeps spans of colon tokens in
-                // type ascription. Here we are trying to retrieve the span of the colon token as
-                // well, but only if it's written without spaces `expr:Ty` and therefore confusable
-                // with `expr::Ty`, only in this case it will match the span from
-                // `type_ascription_path_suggestions`.
-                self.diagnostic_metadata
-                    .current_type_ascription
-                    .push(type_expr.span.between(ty.span));
+            ExprKind::Type(ref _type_expr, ref _ty) => {
                 visit::walk_expr(self, expr);
-                self.diagnostic_metadata.current_type_ascription.pop();
             }
             // `async |x| ...` gets desugared to `|x| async {...}`, so we need to
             // resolve the arguments within the proper scopes so that usages of them inside the
@@ -4089,8 +4151,8 @@
                 ref body,
                 ..
             }) => {
-                self.with_rib(ValueNS, NormalRibKind, |this| {
-                    this.with_label_rib(ClosureOrAsyncRibKind, |this| {
+                self.with_rib(ValueNS, RibKind::Normal, |this| {
+                    this.with_label_rib(RibKind::ClosureOrAsync, |this| {
                         // Resolve arguments:
                         this.resolve_params(&fn_decl.inputs);
                         // No need to resolve return type --
@@ -4114,7 +4176,7 @@
             }) => {
                 self.with_generic_param_rib(
                     &generic_params,
-                    NormalRibKind,
+                    RibKind::Normal,
                     LifetimeRibKind::Generics {
                         binder: expr.id,
                         kind: LifetimeBinderKind::Closure,
@@ -4125,18 +4187,14 @@
             }
             ExprKind::Closure(..) => visit::walk_expr(self, expr),
             ExprKind::Async(..) => {
-                self.with_label_rib(ClosureOrAsyncRibKind, |this| visit::walk_expr(this, expr));
+                self.with_label_rib(RibKind::ClosureOrAsync, |this| visit::walk_expr(this, expr));
             }
             ExprKind::Repeat(ref elem, ref ct) => {
                 self.visit_expr(elem);
-                self.with_lifetime_rib(LifetimeRibKind::AnonConst, |this| {
-                    this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| {
-                        this.resolve_anon_const(ct, IsRepeatExpr::Yes)
-                    })
-                });
+                self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::Yes));
             }
             ExprKind::ConstBlock(ref ct) => {
-                self.resolve_inline_const(ct);
+                self.resolve_anon_const(ct, AnonConstKind::InlineConst);
             }
             ExprKind::Index(ref elem, ref idx) => {
                 self.resolve_expr(elem, Some(expr));
@@ -4229,12 +4287,12 @@
         }
     }
 
-    fn resolve_and_cache_rustdoc_path(&mut self, path_str: &str, ns: Namespace) -> bool {
+    fn resolve_and_cache_rustdoc_path(&mut self, path_str: &str, ns: Namespace) -> Option<Res> {
         // FIXME: This caching may be incorrect in case of multiple `macro_rules`
         // items with the same name in the same module.
         // Also hygiene is not considered.
         let mut doc_link_resolutions = std::mem::take(&mut self.r.doc_link_resolutions);
-        let res = doc_link_resolutions
+        let res = *doc_link_resolutions
             .entry(self.parent_scope.module.nearest_parent_mod().expect_local())
             .or_default()
             .entry((Symbol::intern(path_str), ns))
@@ -4249,8 +4307,7 @@
                     return None;
                 }
                 res
-            })
-            .is_some();
+            });
         self.r.doc_link_resolutions = doc_link_resolutions;
         res
     }
@@ -4285,8 +4342,10 @@
             let mut any_resolved = false;
             let mut need_assoc = false;
             for ns in [TypeNS, ValueNS, MacroNS] {
-                if self.resolve_and_cache_rustdoc_path(&path_str, ns) {
-                    any_resolved = true;
+                if let Some(res) = self.resolve_and_cache_rustdoc_path(&path_str, ns) {
+                    // Rustdoc ignores tool attribute resolutions and attempts
+                    // to resolve their prefixes for diagnostics.
+                    any_resolved = !matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Tool));
                 } else if ns != MacroNS {
                     need_assoc = true;
                 }
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 37fbfad..df65825 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1,7 +1,7 @@
 use crate::diagnostics::{ImportSuggestion, LabelSuggestion, TypoSuggestion};
 use crate::late::{AliasPossibility, LateResolutionVisitor, RibKind};
 use crate::late::{LifetimeBinderKind, LifetimeRes, LifetimeRibKind, LifetimeUseSet};
-use crate::path_names_to_string;
+use crate::{errors, path_names_to_string};
 use crate::{Module, ModuleKind, ModuleOrUniformRoot};
 use crate::{PathResult, PathSource, Segment};
 
@@ -22,19 +22,20 @@
 use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
 use rustc_hir::PrimTy;
 use rustc_session::lint;
-use rustc_session::parse::feature_err;
 use rustc_session::Session;
 use rustc_span::edit_distance::find_best_match_for_name;
 use rustc_span::edition::Edition;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
-use rustc_span::{BytePos, Span};
+use rustc_span::Span;
 
 use std::iter;
 use std::ops::Deref;
 
 use thin_vec::ThinVec;
 
+use super::NoConstantGenericsReason;
+
 type Res = def::Res<ast::NodeId>;
 
 /// A field or associated item from self type suggested in case of resolution failure.
@@ -91,7 +92,7 @@
 /// Description of an elided lifetime.
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
 pub(super) struct MissingLifetime {
-    /// Used to overwrite the resolution with the suggestion, to avoid cascasing errors.
+    /// Used to overwrite the resolution with the suggestion, to avoid cascading errors.
     pub id: NodeId,
     /// Where to suggest adding the lifetime.
     pub span: Span,
@@ -196,8 +197,7 @@
                             .sess
                             .source_map()
                             .span_to_snippet(span)
-                            .map(|snippet| snippet.ends_with(')'))
-                            .unwrap_or(false)
+                            .is_ok_and(|snippet| snippet.ends_with(')'))
                     }
                     Res::Def(
                         DefKind::Ctor(..) | DefKind::AssocFn | DefKind::Const | DefKind::AssocConst,
@@ -315,8 +315,11 @@
         debug!(?res, ?source);
         let base_error = self.make_base_error(path, span, source, res);
         let code = source.error_code(res.is_some());
-        let mut err =
-            self.r.tcx.sess.struct_span_err_with_code(base_error.span, &base_error.msg, code);
+        let mut err = self.r.tcx.sess.struct_span_err_with_code(
+            base_error.span,
+            base_error.msg.clone(),
+            code,
+        );
 
         self.suggest_swapping_misplaced_self_ty_and_trait(&mut err, source, res, base_error.span);
 
@@ -332,7 +335,7 @@
 
         if self.suggest_pattern_match_with_let(&mut err, source, span) {
             // Fallback label.
-            err.span_label(base_error.span, &base_error.fallback_label);
+            err.span_label(base_error.span, base_error.fallback_label);
             return (err, Vec::new());
         }
 
@@ -350,18 +353,15 @@
             return (err, candidates);
         }
 
-        if !self.type_ascription_suggestion(&mut err, base_error.span) {
-            let mut fallback =
-                self.suggest_trait_and_bounds(&mut err, source, res, span, &base_error);
+        let mut fallback = self.suggest_trait_and_bounds(&mut err, source, res, span, &base_error);
 
-            // if we have suggested using pattern matching, then don't add needless suggestions
-            // for typos.
-            fallback |= self.suggest_typo(&mut err, source, path, span, &base_error);
+        // if we have suggested using pattern matching, then don't add needless suggestions
+        // for typos.
+        fallback |= self.suggest_typo(&mut err, source, path, span, &base_error);
 
-            if fallback {
-                // Fallback label.
-                err.span_label(base_error.span, &base_error.fallback_label);
-            }
+        if fallback {
+            // Fallback label.
+            err.span_label(base_error.span, base_error.fallback_label);
         }
         self.err_code_special_cases(&mut err, source, path, span);
 
@@ -408,7 +408,7 @@
         }
         let Some(path_last_segment) = path.last() else { return };
         let item_str = path_last_segment.ident;
-        // Emit help message for fake-self from other languages (e.g., `this` in Javascript).
+        // Emit help message for fake-self from other languages (e.g., `this` in JavaScript).
         if ["this", "my"].contains(&item_str.as_str()) {
             err.span_suggestion_short(
                 span,
@@ -494,24 +494,6 @@
                 .filter(|(_, enum_ty_path)| !enum_ty_path.starts_with("std::prelude::"))
                 .collect();
             if !enum_candidates.is_empty() {
-                if let (PathSource::Type, Some(span)) =
-                    (source, self.diagnostic_metadata.current_type_ascription.last())
-                {
-                    if self
-                        .r
-                        .tcx
-                        .sess
-                        .parse_sess
-                        .type_ascription_path_suggestions
-                        .borrow()
-                        .contains(span)
-                    {
-                        // Already reported this issue on the lhs of the type ascription.
-                        err.downgrade_to_delayed_bug();
-                        return (true, candidates);
-                    }
-                }
-
                 enum_candidates.sort();
 
                 // Contextualize for E0412 "cannot find type", but don't belabor the point
@@ -530,7 +512,7 @@
 
                 err.span_suggestions(
                     span,
-                    &msg,
+                    msg,
                     enum_candidates.into_iter().map(|(_variant_path, enum_ty_path)| enum_ty_path),
                     Applicability::MachineApplicable,
                 );
@@ -577,7 +559,7 @@
                     | AssocSuggestion::AssocType => {
                         err.span_suggestion(
                             span,
-                            &format!("you might have meant to {}", candidate.action()),
+                            format!("you might have meant to {}", candidate.action()),
                             format!("Self::{path_str}"),
                             Applicability::MachineApplicable,
                         );
@@ -598,7 +580,7 @@
 
                 err.span_suggestion(
                     call_span,
-                    &format!("try calling `{ident}` as a method"),
+                    format!("try calling `{ident}` as a method"),
                     format!("self.{path_str}({args_snippet})"),
                     Applicability::MachineApplicable,
                 );
@@ -623,14 +605,14 @@
         }
 
         // Try to find in last block rib
-        if let Some(rib) = &self.last_block_rib && let RibKind::NormalRibKind = rib.kind {
+        if let Some(rib) = &self.last_block_rib && let RibKind::Normal = rib.kind {
             for (ident, &res) in &rib.bindings {
                 if let Res::Local(_) = res && path.len() == 1 &&
                     ident.span.eq_ctxt(path[0].ident.span) &&
                     ident.name == path[0].ident.name {
                     err.span_help(
                         ident.span,
-                        &format!("the binding `{}` is available in a different scope in the same function", path_str),
+                        format!("the binding `{}` is available in a different scope in the same function", path_str),
                     );
                     return (true, candidates);
                 }
@@ -739,7 +721,7 @@
         if let TypoCandidate::Shadowed(res, Some(sugg_span)) = typo_sugg
             && res
                 .opt_def_id()
-                .map_or(false, |id| id.is_local() || is_in_same_file(span, sugg_span))
+                .is_some_and(|id| id.is_local() || is_in_same_file(span, sugg_span))
         {
             err.span_label(
                 sugg_span,
@@ -873,7 +855,7 @@
             // The current function has a `self` parameter, but we were unable to resolve
             // a reference to `self`. This can only happen if the `self` identifier we
             // are resolving came from a different hygiene context.
-            if fn_kind.decl().inputs.get(0).map_or(false, |p| p.is_self()) {
+            if fn_kind.decl().inputs.get(0).is_some_and(|p| p.is_self()) {
                 err.span_label(*span, "this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters");
             } else {
                 let doesnt = if is_assoc_fn {
@@ -911,7 +893,7 @@
                 if let Some(ident) = fn_kind.ident() {
                     err.span_label(
                         ident.span,
-                        &format!("this function {} have a `self` parameter", doesnt),
+                        format!("this function {} have a `self` parameter", doesnt),
                     );
                 }
             }
@@ -1087,7 +1069,7 @@
                     if ident.span == span {
                         err.span_suggestion_verbose(
                             *where_span,
-                            &format!("constrain the associated type to `{}`", ident),
+                            format!("constrain the associated type to `{}`", ident),
                             format!(
                                 "{}: {}<{} = {}>",
                                 self.r
@@ -1288,7 +1270,7 @@
                 }
                 PathSource::Expr(_) | PathSource::TupleStruct(..) | PathSource::Pat => {
                     let span = find_span(&source, err);
-                    err.span_label(self.r.def_span(def_id), &format!("`{path_str}` defined here"));
+                    err.span_label(self.r.def_span(def_id), format!("`{path_str}` defined here"));
 
                     let (tail, descr, applicability, old_fields) = match source {
                         PathSource::Pat => ("", "pattern", Applicability::MachineApplicable, None),
@@ -1332,7 +1314,7 @@
                     };
                     err.span_suggestion(
                         span,
-                        &format!("use struct {} syntax instead", descr),
+                        format!("use struct {} syntax instead", descr),
                         format!("{path_str} {{{pad}{fields}{pad}}}"),
                         applicability,
                     );
@@ -1393,26 +1375,6 @@
                 Res::Def(DefKind::Enum, def_id),
                 PathSource::TupleStruct(..) | PathSource::Expr(..),
             ) => {
-                if self
-                    .diagnostic_metadata
-                    .current_type_ascription
-                    .last()
-                    .map(|sp| {
-                        self.r
-                            .tcx
-                            .sess
-                            .parse_sess
-                            .type_ascription_path_suggestions
-                            .borrow()
-                            .contains(&sp)
-                    })
-                    .unwrap_or(false)
-                {
-                    err.downgrade_to_delayed_bug();
-                    // We already suggested changing `:` into `::` during parsing.
-                    return false;
-                }
-
                 self.suggest_using_enum_variant(err, source, def_id, span);
             }
             (Res::Def(DefKind::Struct, def_id), source) if ns == ValueNS => {
@@ -1494,7 +1456,7 @@
                     if non_visible_spans.len() > 0 {
                         if let Some(fields) = self.r.field_visibility_spans.get(&def_id) {
                             err.multipart_suggestion_verbose(
-                                &format!(
+                                format!(
                                     "consider making the field{} publicly accessible",
                                     pluralize!(fields.len())
                                 ),
@@ -1524,7 +1486,7 @@
                         let span = find_span(&source, err);
                         err.span_label(
                             self.r.def_span(def_id),
-                            &format!("`{path_str}` defined here"),
+                            format!("`{path_str}` defined here"),
                         );
                         err.span_suggestion(
                             span,
@@ -1538,7 +1500,7 @@
             }
             (Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_def_id), _) if ns == ValueNS => {
                 let def_id = self.r.tcx.parent(ctor_def_id);
-                err.span_label(self.r.def_span(def_id), &format!("`{path_str}` defined here"));
+                err.span_label(self.r.def_span(def_id), format!("`{path_str}` defined here"));
                 let fields = self.r.field_def_ids(def_id).map_or_else(
                     || "/* fields */".to_string(),
                     |field_ids| vec!["_"; field_ids.len()].join(", "),
@@ -1669,7 +1631,7 @@
                             .tcx
                             .fn_arg_names(def_id)
                             .first()
-                            .map_or(false, |ident| ident.name == kw::SelfLower),
+                            .is_some_and(|ident| ident.name == kw::SelfLower),
                     };
                     if has_self {
                         return Some(AssocSuggestion::MethodWithSelf { called });
@@ -1728,7 +1690,7 @@
                 }
 
                 // Items in scope
-                if let RibKind::ModuleRibKind(module) = rib.kind {
+                if let RibKind::Module(module) = rib.kind {
                     // Items from this module
                     self.r.add_module_candidates(module, &mut names, &filter_fn, Some(ctxt));
 
@@ -1817,80 +1779,6 @@
         })
     }
 
-    /// Only used in a specific case of type ascription suggestions
-    fn get_colon_suggestion_span(&self, start: Span) -> Span {
-        let sm = self.r.tcx.sess.source_map();
-        start.to(sm.next_point(start))
-    }
-
-    fn type_ascription_suggestion(&self, err: &mut Diagnostic, base_span: Span) -> bool {
-        let sm = self.r.tcx.sess.source_map();
-        let base_snippet = sm.span_to_snippet(base_span);
-        if let Some(&sp) = self.diagnostic_metadata.current_type_ascription.last() {
-            if let Ok(snippet) = sm.span_to_snippet(sp) {
-                let len = snippet.trim_end().len() as u32;
-                if snippet.trim() == ":" {
-                    let colon_sp =
-                        sp.with_lo(sp.lo() + BytePos(len - 1)).with_hi(sp.lo() + BytePos(len));
-                    let mut show_label = true;
-                    if sm.is_multiline(sp) {
-                        err.span_suggestion_short(
-                            colon_sp,
-                            "maybe you meant to write `;` here",
-                            ";",
-                            Applicability::MaybeIncorrect,
-                        );
-                    } else {
-                        let after_colon_sp =
-                            self.get_colon_suggestion_span(colon_sp.shrink_to_hi());
-                        if snippet.len() == 1 {
-                            // `foo:bar`
-                            err.span_suggestion(
-                                colon_sp,
-                                "maybe you meant to write a path separator here",
-                                "::",
-                                Applicability::MaybeIncorrect,
-                            );
-                            show_label = false;
-                            if !self
-                                .r
-                                .tcx
-                                .sess
-                                .parse_sess
-                                .type_ascription_path_suggestions
-                                .borrow_mut()
-                                .insert(colon_sp)
-                            {
-                                err.downgrade_to_delayed_bug();
-                            }
-                        }
-                        if let Ok(base_snippet) = base_snippet {
-                            // Try to find an assignment
-                            let eq_span = sm.span_look_ahead(after_colon_sp, Some("="), Some(50));
-                            if let Ok(ref snippet) = sm.span_to_snippet(eq_span) && snippet == "=" {
-                                err.span_suggestion(
-                                    base_span,
-                                    "maybe you meant to write an assignment here",
-                                    format!("let {}", base_snippet),
-                                    Applicability::MaybeIncorrect,
-                                );
-                                show_label = false;
-                            }
-                        }
-                    }
-                    if show_label {
-                        err.span_label(
-                            base_span,
-                            "expecting a type here because of type ascription",
-                        );
-                    }
-                    return show_label;
-                }
-            }
-        }
-        false
-    }
-
     // try to give a suggestion for this pattern: `name = blah`, which is common in other languages
     // suggest `let name = blah` to introduce a new binding
     fn let_binding_suggestion(&mut self, err: &mut Diagnostic, ident_span: Span) -> bool {
@@ -2014,7 +1902,7 @@
 
                 err.span_suggestions(
                     span,
-                    &msg,
+                    msg,
                     suggestable_variants,
                     Applicability::MaybeIncorrect,
                 );
@@ -2022,17 +1910,17 @@
 
             // If the enum has no tuple variants..
             if non_suggestable_variant_count == variants.len() {
-                err.help(&format!("the enum has no tuple variants {}", source_msg));
+                err.help(format!("the enum has no tuple variants {}", source_msg));
             }
 
             // If there are also non-tuple variants..
             if non_suggestable_variant_count == 1 {
-                err.help(&format!(
+                err.help(format!(
                     "you might have meant {} the enum's non-tuple variant",
                     source_msg
                 ));
             } else if non_suggestable_variant_count >= 1 {
-                err.help(&format!(
+                err.help(format!(
                     "you might have meant {} one of the enum's non-tuple variants",
                     source_msg
                 ));
@@ -2042,10 +1930,9 @@
                 let def_id = self.r.tcx.parent(ctor_def_id);
                 match kind {
                     CtorKind::Const => false,
-                    CtorKind::Fn => !self
-                        .r
-                        .field_def_ids(def_id)
-                        .map_or(false, |field_ids| field_ids.is_empty()),
+                    CtorKind::Fn => {
+                        !self.r.field_def_ids(def_id).is_some_and(|field_ids| field_ids.is_empty())
+                    }
                 }
             };
 
@@ -2282,7 +2169,7 @@
                         lint::builtin::SINGLE_USE_LIFETIMES,
                         param.id,
                         param.ident.span,
-                        &format!("lifetime parameter `{}` only used once", param.ident),
+                        format!("lifetime parameter `{}` only used once", param.ident),
                         lint::BuiltinLintDiagnostics::SingleUseLifetime {
                             param_span: param.ident.span,
                             use_span: Some((use_span, elidable)),
@@ -2301,7 +2188,7 @@
                             lint::builtin::UNUSED_LIFETIMES,
                             param.id,
                             param.ident.span,
-                            &format!("lifetime parameter `{}` never used", param.ident),
+                            format!("lifetime parameter `{}` never used", param.ident),
                             lint::BuiltinLintDiagnostics::SingleUseLifetime {
                                 param_span: param.ident.span,
                                 use_span: None,
@@ -2367,7 +2254,7 @@
                         suggest_note = false; // Avoid displaying the same help multiple times.
                         err.span_label(
                             span,
-                            &format!(
+                            format!(
                                 "lifetime `{}` is missing in item created through this procedural macro",
                                 name,
                             ),
@@ -2428,37 +2315,56 @@
         }
     }
 
-    pub(crate) fn emit_non_static_lt_in_const_generic_error(&self, lifetime_ref: &ast::Lifetime) {
-        struct_span_err!(
-            self.r.tcx.sess,
-            lifetime_ref.ident.span,
-            E0771,
-            "use of non-static lifetime `{}` in const generic",
-            lifetime_ref.ident
-        )
-        .note(
-            "for more information, see issue #74052 \
-            <https://github.com/rust-lang/rust/issues/74052>",
-        )
-        .emit();
+    pub(crate) fn emit_non_static_lt_in_const_param_ty_error(&self, lifetime_ref: &ast::Lifetime) {
+        self.r
+            .tcx
+            .sess
+            .create_err(errors::ParamInTyOfConstParam {
+                span: lifetime_ref.ident.span,
+                name: lifetime_ref.ident.name,
+                param_kind: Some(errors::ParamKindInTyOfConstParam::Lifetime),
+            })
+            .emit();
     }
 
     /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
     /// This function will emit an error if `generic_const_exprs` is not enabled, the body identified by
     /// `body_id` is an anonymous constant and `lifetime_ref` is non-static.
-    pub(crate) fn maybe_emit_forbidden_non_static_lifetime_error(
+    pub(crate) fn emit_forbidden_non_static_lifetime_error(
         &self,
+        cause: NoConstantGenericsReason,
         lifetime_ref: &ast::Lifetime,
     ) {
-        let feature_active = self.r.tcx.sess.features_untracked().generic_const_exprs;
-        if !feature_active {
-            feature_err(
-                &self.r.tcx.sess.parse_sess,
-                sym::generic_const_exprs,
-                lifetime_ref.ident.span,
-                "a non-static lifetime is not allowed in a `const`",
-            )
-            .emit();
+        match cause {
+            NoConstantGenericsReason::IsEnumDiscriminant => {
+                self.r
+                    .tcx
+                    .sess
+                    .create_err(errors::ParamInEnumDiscriminant {
+                        span: lifetime_ref.ident.span,
+                        name: lifetime_ref.ident.name,
+                        param_kind: errors::ParamKindInEnumDiscriminant::Lifetime,
+                    })
+                    .emit();
+            }
+            NoConstantGenericsReason::NonTrivialConstArg => {
+                assert!(!self.r.tcx.features().generic_const_exprs);
+                self.r
+                    .tcx
+                    .sess
+                    .create_err(errors::ParamInNonTrivialAnonConst {
+                        span: lifetime_ref.ident.span,
+                        name: lifetime_ref.ident.name,
+                        param_kind: errors::ParamKindInNonTrivialAnonConst::Lifetime,
+                        help: self
+                            .r
+                            .tcx
+                            .sess
+                            .is_nightly_build()
+                            .then_some(errors::ParamInNonTrivialAnonConstHelp),
+                    })
+                    .emit();
+            }
         }
     }
 
@@ -2573,13 +2479,13 @@
                     )];
                 }
             } else if num_params == 1 {
-                err.help(&format!(
+                err.help(format!(
                     "this function's return type contains a borrowed value, \
                  but the signature does not say which {} it is borrowed from",
                     m
                 ));
             } else {
-                err.help(&format!(
+                err.help(format!(
                     "this function's return type contains a borrowed value, \
                  but the signature does not say whether it is borrowed from {}",
                     m
@@ -2648,7 +2554,7 @@
             }
             1 => {
                 err.multipart_suggestion_verbose(
-                    &format!("consider using the `{}` lifetime", existing_name),
+                    format!("consider using the `{}` lifetime", existing_name),
                     spans_suggs,
                     Applicability::MaybeIncorrect,
                 );
@@ -2699,7 +2605,7 @@
     let shadower = shadower.span;
     let mut err = sess.struct_span_warn(
         shadower,
-        &format!("label name `{}` shadows a label name that is already in scope", name),
+        format!("label name `{}` shadows a label name that is already in scope", name),
     );
     err.span_label(orig, "first declared here");
     err.span_label(shadower, format!("label `{}` already in scope", name));
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index b820d56..3d2bd84 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -21,6 +21,9 @@
 #[macro_use]
 extern crate tracing;
 
+use errors::{
+    ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst, ParamKindInTyOfConstParam,
+};
 use rustc_arena::{DroplessArena, TypedArena};
 use rustc_ast::node_id::NodeMap;
 use rustc_ast::{self as ast, attr, NodeId, CRATE_NODE_ID};
@@ -33,17 +36,18 @@
     Applicability, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, SubdiagnosticMessage,
 };
 use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind};
+use rustc_fluent_macro::fluent_messages;
 use rustc_hir::def::Namespace::{self, *};
 use rustc_hir::def::{self, CtorOf, DefKind, DocLinkResMap, LifetimeRes, PartialRes, PerNS};
 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap, LocalDefIdSet};
 use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE};
 use rustc_hir::definitions::DefPathData;
 use rustc_hir::TraitCandidate;
-use rustc_index::vec::IndexVec;
-use rustc_macros::fluent_messages;
+use rustc_index::IndexVec;
 use rustc_metadata::creader::{CStore, CrateLoader};
 use rustc_middle::metadata::ModChild;
 use rustc_middle::middle::privacy::EffectiveVisibilities;
+use rustc_middle::query::Providers;
 use rustc_middle::span_bug;
 use rustc_middle::ty::{self, MainDefinition, RegisteredTools, TyCtxt};
 use rustc_middle::ty::{ResolverGlobalCtxt, ResolverOutputs};
@@ -81,6 +85,7 @@
 
 fluent_messages! { "../messages.ftl" }
 
+#[derive(Debug)]
 enum Weak {
     Yes,
     No,
@@ -101,7 +106,7 @@
 /// A specific scope in which a name can be looked up.
 /// This enum is currently used only for early resolution (imports and macros),
 /// but not for late resolution yet.
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
 enum Scope<'a> {
     DeriveHelpers(LocalExpnId),
     DeriveHelpersCompat,
@@ -223,11 +228,15 @@
     /// Error E0128: generic parameters with a default cannot use forward-declared identifiers.
     ForwardDeclaredGenericParam,
     /// ERROR E0770: the type of const parameters must not depend on other generic parameters.
-    ParamInTyOfConstParam(Symbol),
+    ParamInTyOfConstParam { name: Symbol, param_kind: Option<ParamKindInTyOfConstParam> },
     /// generic parameters must not be used inside const evaluations.
     ///
     /// This error is only emitted when using `min_const_generics`.
-    ParamInNonTrivialAnonConst { name: Symbol, is_type: bool },
+    ParamInNonTrivialAnonConst { name: Symbol, param_kind: ParamKindInNonTrivialAnonConst },
+    /// generic parameters must not be used inside enum discriminants.
+    ///
+    /// This error is emitted even with `generic_const_exprs`.
+    ParamInEnumDiscriminant { name: Symbol, param_kind: ParamKindInEnumDiscriminant },
     /// Error E0735: generic parameters with a default cannot use `Self`
     SelfInGenericParamDefault,
     /// Error E0767: use of unreachable label
@@ -244,6 +253,8 @@
     TraitImplDuplicate { name: Symbol, trait_item_span: Span, old_span: Span },
     /// Inline asm `sym` operand must refer to a `fn` or `static`.
     InvalidAsmSym,
+    /// `self` used instead of `Self` in a generic parameter
+    LowercaseSelf,
 }
 
 enum VisResolutionError<'a> {
@@ -459,6 +470,13 @@
     disambiguator: u32,
 }
 
+impl BindingKey {
+    fn new(ident: Ident, ns: Namespace) -> Self {
+        let ident = ident.normalize_to_macros_2_0();
+        BindingKey { ident, ns, disambiguator: 0 }
+    }
+}
+
 type Resolutions<'a> = RefCell<FxIndexMap<BindingKey, &'a RefCell<NameResolution<'a>>>>;
 
 /// One node in the tree of modules.
@@ -909,8 +927,7 @@
 
     /// `CrateNum` resolutions of `extern crate` items.
     extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
-    module_children_non_reexports: LocalDefIdMap<Vec<LocalDefId>>,
-    module_children_reexports: LocalDefIdMap<Vec<ModChild>>,
+    module_children: LocalDefIdMap<Vec<ModChild>>,
     trait_map: NodeMap<Vec<TraitCandidate>>,
 
     /// A map from nodes to anonymous modules.
@@ -934,6 +951,7 @@
     empty_module: Module<'a>,
     module_map: FxHashMap<DefId, Module<'a>>,
     binding_parent_modules: FxHashMap<Interned<'a, NameBinding<'a>>, Module<'a>>,
+
     underscore_disambiguator: u32,
 
     /// Maps glob imports to the names of items actually imported.
@@ -1260,8 +1278,7 @@
             lifetimes_res_map: Default::default(),
             extra_lifetime_params_map: Default::default(),
             extern_crate_map: Default::default(),
-            module_children_non_reexports: Default::default(),
-            module_children_reexports: Default::default(),
+            module_children: Default::default(),
             trait_map: NodeMap::default(),
             underscore_disambiguator: 0,
             empty_module,
@@ -1399,8 +1416,7 @@
             has_pub_restricted,
             effective_visibilities,
             extern_crate_map,
-            module_children_non_reexports: self.module_children_non_reexports,
-            module_children_reexports: self.module_children_reexports,
+            module_children: self.module_children,
             glob_map,
             maybe_unused_trait_imports,
             main_def,
@@ -1461,7 +1477,7 @@
     }
 
     fn is_builtin_macro(&mut self, res: Res) -> bool {
-        self.get_macro(res).map_or(false, |macro_data| macro_data.ext.builtin_name.is_some())
+        self.get_macro(res).is_some_and(|macro_data| macro_data.ext.builtin_name.is_some())
     }
 
     fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId {
@@ -1588,7 +1604,7 @@
         import_ids
     }
 
-    fn new_key(&mut self, ident: Ident, ns: Namespace) -> BindingKey {
+    fn new_disambiguated_key(&mut self, ident: Ident, ns: Namespace) -> BindingKey {
         let ident = ident.normalize_to_macros_2_0();
         let disambiguator = if ident.name == kw::Underscore {
             self.underscore_disambiguator += 1;
@@ -2020,6 +2036,6 @@
     }
 }
 
-pub fn provide(providers: &mut ty::query::Providers) {
+pub fn provide(providers: &mut Providers) {
     providers.registered_tools = macros::registered_tools;
 }
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 22b014c..df5c16a 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -1,7 +1,7 @@
 //! A bunch of methods and structures more or less related to resolving macros and
 //! interface provided by `Resolver` to macro expander.
 
-use crate::errors::{AddAsNonDerive, MacroExpectedFound, RemoveSurroundingDerive};
+use crate::errors::{self, AddAsNonDerive, MacroExpectedFound, RemoveSurroundingDerive};
 use crate::Namespace::*;
 use crate::{BuiltinMacroState, Determinacy};
 use crate::{DeriveData, Finalize, ParentScope, ResolutionError, Resolver, ScopeSet};
@@ -121,7 +121,7 @@
                     if let Some(old_ident) = registered_tools.replace(ident) {
                         let msg = format!("{} `{}` was already registered", "tool", ident);
                         tcx.sess
-                            .struct_span_err(ident.span, &msg)
+                            .struct_span_err(ident.span, msg)
                             .span_label(old_ident.span, "already registered here")
                             .emit();
                     }
@@ -130,7 +130,7 @@
                     let msg = format!("`{}` only accepts identifiers", sym::register_tool);
                     let span = nested_meta.span();
                     tcx.sess
-                        .struct_span_err(span, &msg)
+                        .struct_span_err(span, msg)
                         .span_label(span, "not an identifier")
                         .emit();
                 }
@@ -202,7 +202,7 @@
             self.tcx
                 .sess
                 .diagnostic()
-                .bug(&format!("built-in macro `{}` was already registered", name));
+                .bug(format!("built-in macro `{}` was already registered", name));
         }
     }
 
@@ -315,7 +315,7 @@
                 UNUSED_MACROS,
                 node_id,
                 ident.span,
-                &format!("unused macro definition: `{}`", ident.name),
+                format!("unused macro definition: `{}`", ident.name),
             );
         }
         for (&(def_id, arm_i), &(ident, rule_span)) in self.unused_macro_rules.iter() {
@@ -328,7 +328,7 @@
                 UNUSED_MACRO_RULES,
                 node_id,
                 rule_span,
-                &format!(
+                format!(
                     "{} rule of macro `{}` is never used",
                     crate::diagnostics::ordinalize(arm_i + 1),
                     ident.name
@@ -436,9 +436,7 @@
                 // HACK(Urgau): This shouldn't be necessary
                 PathResult::Failed { is_error_from_last_segment: false, .. } => {
                     self.tcx.sess
-                        .struct_span_err(span, "not sure whether the path is accessible or not")
-                        .note("the type may have associated items, but we are currently not checking them")
-                        .emit();
+                        .emit_err(errors::CfgAccessibleUnsure { span });
 
                     // If we get a partially resolved NonModule in one namespace, we should get the
                     // same result in any other namespaces, so we can return early.
@@ -513,10 +511,10 @@
                 if let Some(def_id) = def_id.as_local() {
                     self.unused_macros.remove(&def_id);
                     if self.proc_macro_stubs.contains(&def_id) {
-                        self.tcx.sess.span_err(
-                            path.span,
-                            "can't use a procedural macro from the same crate that defines it",
-                        );
+                        self.tcx.sess.emit_err(errors::ProcMacroSameCrate {
+                            span: path.span,
+                            is_test: self.tcx.sess.is_test_crate(),
+                        });
                     }
                 }
             }
@@ -700,7 +698,7 @@
                         Segment::names_to_string(path)
                     );
                     let msg_note = "import resolution is stuck, try simplifying macro imports";
-                    this.tcx.sess.struct_span_err(span, &msg).note(msg_note).emit();
+                    this.tcx.sess.struct_span_err(span, msg).note(msg_note).emit();
                 }
             }
         };
@@ -790,7 +788,7 @@
                 Err(..) => {
                     let expected = kind.descr_expected();
                     let msg = format!("cannot find {} `{}` in this scope", expected, ident);
-                    let mut err = self.tcx.sess.struct_span_err(ident.span, &msg);
+                    let mut err = self.tcx.sess.struct_span_err(ident.span, msg);
                     self.unresolved_macro_suggestions(&mut err, kind, &parent_scope, ident);
                     err.emit();
                 }
@@ -825,8 +823,7 @@
                 let is_allowed = |feature| {
                     self.active_features.contains(&feature) || span.allows_unstable(feature)
                 };
-                let allowed_by_implication =
-                    implied_by.map(|feature| is_allowed(feature)).unwrap_or(false);
+                let allowed_by_implication = implied_by.is_some_and(|feature| is_allowed(feature));
                 if !is_allowed(feature) && !allowed_by_implication {
                     let lint_buffer = &mut self.lint_buffer;
                     let soft_handler =
@@ -868,9 +865,9 @@
             if kind != NonMacroAttrKind::Tool && binding.map_or(true, |b| b.is_import()) {
                 let msg =
                     format!("cannot use {} {} through an import", kind.article(), kind.descr());
-                let mut err = self.tcx.sess.struct_span_err(span, &msg);
+                let mut err = self.tcx.sess.struct_span_err(span, msg);
                 if let Some(binding) = binding {
-                    err.span_note(binding.span, &format!("the {} imported here", kind.descr()));
+                    err.span_note(binding.span, format!("the {} imported here", kind.descr()));
                 }
                 err.emit();
             }
@@ -885,7 +882,7 @@
             if macro_kind.is_some() && sub_namespace_match(macro_kind, Some(MacroKind::Attr)) {
                 self.tcx.sess.span_err(
                     ident.span,
-                    &format!("name `{}` is reserved in attribute namespace", ident),
+                    format!("name `{}` is reserved in attribute namespace", ident),
                 );
             }
         }
@@ -929,7 +926,7 @@
                 }
             } else {
                 let msg = format!("cannot find a built-in macro with name `{}`", item.ident);
-                self.tcx.sess.span_err(item.span, &msg);
+                self.tcx.sess.span_err(item.span, msg);
             }
         }
 
diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs
index 9eae99b..d433391 100644
--- a/compiler/rustc_resolve/src/rustdoc.rs
+++ b/compiler/rustc_resolve/src/rustdoc.rs
@@ -367,6 +367,7 @@
     let link = link.strip_suffix("{}").unwrap_or(link);
     let link = link.strip_suffix("[]").unwrap_or(link);
     let link = if link != "!" { link.strip_suffix('!').unwrap_or(link) } else { link };
+    let link = link.trim();
     strip_generics_from_path(link).unwrap_or_else(|_| link.into())
 }