diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs
index 497a28354d813..58996a9db78ad 100644
--- a/compiler/rustc_codegen_gcc/src/lib.rs
+++ b/compiler/rustc_codegen_gcc/src/lib.rs
@@ -139,14 +139,12 @@ impl CodegenBackend for GccCodegenBackend {
 }
 
 impl ExtraBackendMethods for GccCodegenBackend {
-    fn new_metadata<'tcx>(&self, _tcx: TyCtxt<'tcx>, _mod_name: &str) -> Self::Module {
-        GccContext {
+    fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, module_name: &str, kind: AllocatorKind, has_alloc_error_handler: bool) -> Self::Module {
+        let mut mods = GccContext {
             context: Context::default(),
-        }
-    }
-
-    fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, mods: &mut Self::Module, module_name: &str, kind: AllocatorKind, has_alloc_error_handler: bool) {
-        unsafe { allocator::codegen(tcx, mods, module_name, kind, has_alloc_error_handler) }
+        };
+        unsafe { allocator::codegen(tcx, &mut mods, module_name, kind, has_alloc_error_handler); }
+        mods
     }
 
     fn compile_codegen_unit<'tcx>(&self, tcx: TyCtxt<'tcx>, cgu_name: Symbol) -> (ModuleCodegen<Self::Module>, u64) {
@@ -213,7 +211,7 @@ impl WriteBackendMethods for GccCodegenBackend {
                     unimplemented!();
                 }
             };
-        Ok(LtoModuleCodegen::Fat { module: Some(module), _serialized_bitcode: vec![] })
+        Ok(LtoModuleCodegen::Fat { module, _serialized_bitcode: vec![] })
     }
 
     fn run_thin_lto(_cgcx: &CodegenContext<Self>, _modules: Vec<(String, Self::ThinBuffer)>, _cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>) -> Result<(Vec<LtoModuleCodegen<Self>>, Vec<WorkProduct>), FatalError> {
@@ -229,7 +227,12 @@ impl WriteBackendMethods for GccCodegenBackend {
         Ok(())
     }
 
-    unsafe fn optimize_thin(_cgcx: &CodegenContext<Self>, _thin: &mut ThinModule<Self>) -> Result<ModuleCodegen<Self::Module>, FatalError> {
+    fn optimize_fat(_cgcx: &CodegenContext<Self>, _module: &mut ModuleCodegen<Self::Module>) -> Result<(), FatalError> {
+        // TODO(antoyo)
+        Ok(())
+    }
+
+    unsafe fn optimize_thin(_cgcx: &CodegenContext<Self>, _thin: ThinModule<Self>) -> Result<ModuleCodegen<Self::Module>, FatalError> {
         unimplemented!();
     }
 
@@ -245,11 +248,6 @@ impl WriteBackendMethods for GccCodegenBackend {
         unimplemented!();
     }
 
-    fn run_lto_pass_manager(_cgcx: &CodegenContext<Self>, _module: &ModuleCodegen<Self::Module>, _config: &ModuleConfig, _thin: bool) -> Result<(), FatalError> {
-        // TODO(antoyo)
-        Ok(())
-    }
-
     fn run_link(cgcx: &CodegenContext<Self>, diag_handler: &Handler, modules: Vec<ModuleCodegen<Self::Module>>) -> Result<ModuleCodegen<Self::Module>, FatalError> {
         back::write::link(cgcx, diag_handler, modules)
     }
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index 5c63bd8c1bd8d..b5b2a27d2378d 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -6,9 +6,7 @@ use crate::llvm::{self, build_string, False, True};
 use crate::{llvm_util, LlvmCodegenBackend, ModuleLlvm};
 use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared};
 use rustc_codegen_ssa::back::symbol_export;
-use rustc_codegen_ssa::back::write::{
-    CodegenContext, FatLTOInput, ModuleConfig, TargetMachineFactoryConfig,
-};
+use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, TargetMachineFactoryConfig};
 use rustc_codegen_ssa::traits::*;
 use rustc_codegen_ssa::{looks_like_rust_object_file, ModuleCodegen, ModuleKind};
 use rustc_data_structures::fx::FxHashMap;
@@ -353,7 +351,7 @@ fn fat_lto(
         }
     }
 
-    Ok(LtoModuleCodegen::Fat { module: Some(module), _serialized_bitcode: serialized_bitcode })
+    Ok(LtoModuleCodegen::Fat { module, _serialized_bitcode: serialized_bitcode })
 }
 
 crate struct Linker<'a>(&'a mut llvm::Linker<'a>);
@@ -578,11 +576,11 @@ fn thin_lto(
 pub(crate) fn run_pass_manager(
     cgcx: &CodegenContext<LlvmCodegenBackend>,
     diag_handler: &Handler,
-    module: &ModuleCodegen<ModuleLlvm>,
-    config: &ModuleConfig,
+    module: &mut ModuleCodegen<ModuleLlvm>,
     thin: bool,
 ) -> Result<(), FatalError> {
     let _timer = cgcx.prof.extra_verbose_generic_activity("LLVM_lto_optimize", &*module.name);
+    let config = cgcx.config(module.kind);
 
     // Now we have one massive module inside of llmod. Time to run the
     // LTO-specific optimization passes that LLVM provides.
@@ -726,7 +724,7 @@ impl Drop for ThinBuffer {
 }
 
 pub unsafe fn optimize_thin_module(
-    thin_module: &mut ThinModule<LlvmCodegenBackend>,
+    thin_module: ThinModule<LlvmCodegenBackend>,
     cgcx: &CodegenContext<LlvmCodegenBackend>,
 ) -> Result<ModuleCodegen<ModuleLlvm>, FatalError> {
     let diag_handler = cgcx.create_diag_handler();
@@ -743,7 +741,7 @@ pub unsafe fn optimize_thin_module(
     // that LLVM Context and Module.
     let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names);
     let llmod_raw = parse_module(llcx, module_name, thin_module.data(), &diag_handler)? as *const _;
-    let module = ModuleCodegen {
+    let mut module = ModuleCodegen {
         module_llvm: ModuleLlvm { llmod_raw, llcx, tm },
         name: thin_module.name().to_string(),
         kind: ModuleKind::Regular,
@@ -859,8 +857,7 @@ pub unsafe fn optimize_thin_module(
         // little differently.
         {
             info!("running thin lto passes over {}", module.name);
-            let config = cgcx.config(module.kind);
-            run_pass_manager(cgcx, &diag_handler, &module, config, true)?;
+            run_pass_manager(cgcx, &diag_handler, &mut module, true)?;
             save_temp_bitcode(cgcx, &module, "thin-lto-after-pm");
         }
     }
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index 3152c505af0e5..b035923956954 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -104,19 +104,18 @@ impl Drop for TimeTraceProfiler {
 }
 
 impl ExtraBackendMethods for LlvmCodegenBackend {
-    fn new_metadata(&self, tcx: TyCtxt<'_>, mod_name: &str) -> ModuleLlvm {
-        ModuleLlvm::new_metadata(tcx, mod_name)
-    }
-
     fn codegen_allocator<'tcx>(
         &self,
         tcx: TyCtxt<'tcx>,
-        module_llvm: &mut ModuleLlvm,
         module_name: &str,
         kind: AllocatorKind,
         has_alloc_error_handler: bool,
-    ) {
-        unsafe { allocator::codegen(tcx, module_llvm, module_name, kind, has_alloc_error_handler) }
+    ) -> ModuleLlvm {
+        let mut module_llvm = ModuleLlvm::new_metadata(tcx, module_name);
+        unsafe {
+            allocator::codegen(tcx, &mut module_llvm, module_name, kind, has_alloc_error_handler);
+        }
+        module_llvm
     }
     fn compile_codegen_unit(
         &self,
@@ -210,9 +209,16 @@ impl WriteBackendMethods for LlvmCodegenBackend {
     ) -> Result<(), FatalError> {
         back::write::optimize(cgcx, diag_handler, module, config)
     }
+    fn optimize_fat(
+        cgcx: &CodegenContext<Self>,
+        module: &mut ModuleCodegen<Self::Module>,
+    ) -> Result<(), FatalError> {
+        let diag_handler = cgcx.create_diag_handler();
+        back::lto::run_pass_manager(cgcx, &diag_handler, module, false)
+    }
     unsafe fn optimize_thin(
         cgcx: &CodegenContext<Self>,
-        thin: &mut ThinModule<Self>,
+        thin: ThinModule<Self>,
     ) -> Result<ModuleCodegen<Self::Module>, FatalError> {
         back::lto::optimize_thin_module(thin, cgcx)
     }
@@ -230,15 +236,6 @@ impl WriteBackendMethods for LlvmCodegenBackend {
     fn serialize_module(module: ModuleCodegen<Self::Module>) -> (String, Self::ModuleBuffer) {
         (module.name, back::lto::ModuleBuffer::new(module.module_llvm.llmod()))
     }
-    fn run_lto_pass_manager(
-        cgcx: &CodegenContext<Self>,
-        module: &ModuleCodegen<Self::Module>,
-        config: &ModuleConfig,
-        thin: bool,
-    ) -> Result<(), FatalError> {
-        let diag_handler = cgcx.create_diag_handler();
-        back::lto::run_pass_manager(cgcx, &diag_handler, module, config, thin)
-    }
 }
 
 unsafe impl Send for LlvmCodegenBackend {} // Llvm is on a per-thread basis
diff --git a/compiler/rustc_codegen_ssa/src/back/lto.rs b/compiler/rustc_codegen_ssa/src/back/lto.rs
index d6ae689f254b1..cb6244050df24 100644
--- a/compiler/rustc_codegen_ssa/src/back/lto.rs
+++ b/compiler/rustc_codegen_ssa/src/back/lto.rs
@@ -42,7 +42,7 @@ pub struct ThinShared<B: WriteBackendMethods> {
 
 pub enum LtoModuleCodegen<B: WriteBackendMethods> {
     Fat {
-        module: Option<ModuleCodegen<B::Module>>,
+        module: ModuleCodegen<B::Module>,
         _serialized_bitcode: Vec<SerializedModule<B::ModuleBuffer>>,
     },
 
@@ -64,19 +64,15 @@ impl<B: WriteBackendMethods> LtoModuleCodegen<B> {
     /// It's intended that the module returned is immediately code generated and
     /// dropped, and then this LTO module is dropped.
     pub unsafe fn optimize(
-        &mut self,
+        self,
         cgcx: &CodegenContext<B>,
     ) -> Result<ModuleCodegen<B::Module>, FatalError> {
-        match *self {
-            LtoModuleCodegen::Fat { ref mut module, .. } => {
-                let module = module.take().unwrap();
-                {
-                    let config = cgcx.config(module.kind);
-                    B::run_lto_pass_manager(cgcx, &module, config, false)?;
-                }
+        match self {
+            LtoModuleCodegen::Fat { mut module, .. } => {
+                B::optimize_fat(cgcx, &mut module)?;
                 Ok(module)
             }
-            LtoModuleCodegen::Thin(ref mut thin) => B::optimize_thin(cgcx, thin),
+            LtoModuleCodegen::Thin(thin) => B::optimize_thin(cgcx, thin),
         }
     }
 
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 98dc5fe8d6424..88293dec01cac 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -889,7 +889,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
 
 fn execute_lto_work_item<B: ExtraBackendMethods>(
     cgcx: &CodegenContext<B>,
-    mut module: lto::LtoModuleCodegen<B>,
+    module: lto::LtoModuleCodegen<B>,
     module_config: &ModuleConfig,
 ) -> Result<WorkItemResult<B>, FatalError> {
     let module = unsafe { module.optimize(cgcx)? };
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 019c9c179d8e1..5bc95614c197c 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -575,15 +575,8 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
     } else if let Some(kind) = tcx.allocator_kind(()) {
         let llmod_id =
             cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("allocator")).to_string();
-        let mut module_llvm = backend.new_metadata(tcx, &llmod_id);
-        tcx.sess.time("write_allocator_module", || {
-            backend.codegen_allocator(
-                tcx,
-                &mut module_llvm,
-                &llmod_id,
-                kind,
-                tcx.lang_items().oom().is_some(),
-            )
+        let module_llvm = tcx.sess.time("write_allocator_module", || {
+            backend.codegen_allocator(tcx, &llmod_id, kind, tcx.lang_items().oom().is_some())
         });
 
         Some(ModuleCodegen { name: llmod_id, module_llvm, kind: ModuleKind::Allocator })
diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs
index 856b774258316..1e53c73d1bb4a 100644
--- a/compiler/rustc_codegen_ssa/src/traits/backend.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs
@@ -114,15 +114,13 @@ pub trait CodegenBackend {
 }
 
 pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Send + Sync {
-    fn new_metadata(&self, sess: TyCtxt<'_>, mod_name: &str) -> Self::Module;
     fn codegen_allocator<'tcx>(
         &self,
         tcx: TyCtxt<'tcx>,
-        module_llvm: &mut Self::Module,
         module_name: &str,
         kind: AllocatorKind,
         has_alloc_error_handler: bool,
-    );
+    ) -> Self::Module;
     /// This generates the codegen unit and returns it along with
     /// a `u64` giving an estimate of the unit's processing cost.
     fn compile_codegen_unit(
diff --git a/compiler/rustc_codegen_ssa/src/traits/write.rs b/compiler/rustc_codegen_ssa/src/traits/write.rs
index 93fbee2b49bb5..e54ec34f1ce37 100644
--- a/compiler/rustc_codegen_ssa/src/traits/write.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/write.rs
@@ -41,9 +41,13 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
         module: &ModuleCodegen<Self::Module>,
         config: &ModuleConfig,
     ) -> Result<(), FatalError>;
+    fn optimize_fat(
+        cgcx: &CodegenContext<Self>,
+        llmod: &mut ModuleCodegen<Self::Module>,
+    ) -> Result<(), FatalError>;
     unsafe fn optimize_thin(
         cgcx: &CodegenContext<Self>,
-        thin: &mut ThinModule<Self>,
+        thin: ThinModule<Self>,
     ) -> Result<ModuleCodegen<Self::Module>, FatalError>;
     unsafe fn codegen(
         cgcx: &CodegenContext<Self>,
@@ -53,12 +57,6 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
     ) -> Result<CompiledModule, FatalError>;
     fn prepare_thin(module: ModuleCodegen<Self::Module>) -> (String, Self::ThinBuffer);
     fn serialize_module(module: ModuleCodegen<Self::Module>) -> (String, Self::ModuleBuffer);
-    fn run_lto_pass_manager(
-        cgcx: &CodegenContext<Self>,
-        llmod: &ModuleCodegen<Self::Module>,
-        config: &ModuleConfig,
-        thin: bool,
-    ) -> Result<(), FatalError>;
 }
 
 pub trait ThinBufferMethods: Send + Sync {
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 0dff71be4b82c..188ca8048055c 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -2561,16 +2561,12 @@ pub enum Rvalue<'tcx> {
     UnaryOp(UnOp, Operand<'tcx>),
 
     /// Computes the discriminant of the place, returning it as an integer of type
-    /// [`discriminant_ty`].
+    /// [`discriminant_ty`]. Returns zero for types without discriminant.
     ///
     /// The validity requirements for the underlying value are undecided for this rvalue, see
     /// [#91095]. Note too that the value of the discriminant is not the same thing as the
     /// variant index; use [`discriminant_for_variant`] to convert.
     ///
-    /// For types defined in the source code as enums, this is well behaved. This is also well
-    /// formed for other types, but yields no particular value - there is no reason it couldn't be
-    /// defined to yield eg zero though.
-    ///
     /// [`discriminant_ty`]: crate::ty::Ty::discriminant_ty
     /// [#91095]: https://github.com/rust-lang/rust/issues/91095
     /// [`discriminant_for_variant`]: crate::ty::Ty::discriminant_for_variant
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 10f1daf112951..77a03428c1664 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -1020,7 +1020,7 @@ impl<'a> Parser<'a> {
                                 &format!("`{}` must come before `{}`", invalid_qual, current_qual),
                                 format!("{} {}", invalid_qual, current_qual),
                                 Applicability::MachineApplicable,
-                            ).note("keyword order for functions declaration is `default`, `pub`, `const`, `async`, `unsafe`, `extern`");
+                            ).note("keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`");
                     }
                 }
                 Err(err)
@@ -2086,7 +2086,7 @@ impl<'a> Parser<'a> {
                                     &format!("`{misplaced_qual}` must come before `{current_qual}`"),
                                     format!("{misplaced_qual} {current_qual}"),
                                     Applicability::MachineApplicable,
-                                ).note("keyword order for functions declaration is `default`, `pub`, `const`, `async`, `unsafe`, `extern`");
+                                ).note("keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`");
                         }
                     }
                     // Recover incorrect visibility order such as `async pub`
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 18ce359524da2..baaab33d71f50 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -1179,7 +1179,7 @@ impl<'a> Resolver<'a> {
                         ConstantItemRibKind(trivial, _) => {
                             let features = self.session.features_untracked();
                             // HACK(min_const_generics): We currently only allow `N` or `{ N }`.
-                            if !(trivial || features.generic_const_exprs) {
+                            if !(trivial == HasGenericParams::Yes || features.generic_const_exprs) {
                                 // 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 concrete later on.
@@ -1267,7 +1267,7 @@ impl<'a> Resolver<'a> {
                         ConstantItemRibKind(trivial, _) => {
                             let features = self.session.features_untracked();
                             // HACK(min_const_generics): We currently only allow `N` or `{ N }`.
-                            if !(trivial || features.generic_const_exprs) {
+                            if !(trivial == HasGenericParams::Yes || features.generic_const_exprs) {
                                 if let Some(span) = finalize {
                                     self.report_error(
                                         span,
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index b89b9c376af63..ab353128cbcce 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -94,6 +94,12 @@ crate enum HasGenericParams {
     No,
 }
 
+impl HasGenericParams {
+    fn force_yes_if(self, b: bool) -> Self {
+        if b { Self::Yes } else { self }
+    }
+}
+
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 crate enum ConstantItemKind {
     Const,
@@ -125,9 +131,9 @@ crate enum RibKind<'a> {
 
     /// We're in a constant item. Can't refer to dynamic stuff.
     ///
-    /// The `bool` indicates if this constant may reference generic parameters
-    /// and is used to only allow generic parameters to be used in trivial constant expressions.
-    ConstantItemRibKind(bool, Option<(Ident, ConstantItemKind)>),
+    /// The item may reference generic parameters in trivial constant expressions.
+    /// All other constants aren't allowed to use generic params at all.
+    ConstantItemRibKind(HasGenericParams, Option<(Ident, ConstantItemKind)>),
 
     /// We passed through a module.
     ModuleRibKind(Module<'a>),
@@ -826,19 +832,24 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
                             // 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, true, None, |this| {
-                                this.smart_resolve_path(
-                                    ty.id,
-                                    qself.as_ref(),
-                                    path,
-                                    PathSource::Expr(None),
-                                );
-
-                                if let Some(ref qself) = *qself {
-                                    this.visit_ty(&qself.ty);
-                                }
-                                this.visit_path(path, ty.id);
-                            });
+                            self.with_constant_rib(
+                                IsRepeatExpr::No,
+                                HasGenericParams::Yes,
+                                None,
+                                |this| {
+                                    this.smart_resolve_path(
+                                        ty.id,
+                                        qself.as_ref(),
+                                        path,
+                                        PathSource::Expr(None),
+                                    );
+
+                                    if let Some(ref qself) = *qself {
+                                        this.visit_ty(&qself.ty);
+                                    }
+                                    this.visit_path(path, ty.id);
+                                },
+                            );
 
                             self.diagnostic_metadata.currently_processing_generics = prev;
                             return;
@@ -1684,7 +1695,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                                                     // not used as part of the type system, this is far less surprising.
                                                     this.with_constant_rib(
                                                         IsRepeatExpr::No,
-                                                        true,
+                                                        HasGenericParams::Yes,
                                                         None,
                                                         |this| this.visit_expr(expr),
                                                     );
@@ -1763,7 +1774,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                         // so it doesn't matter whether this is a trivial constant.
                         this.with_constant_rib(
                             IsRepeatExpr::No,
-                            true,
+                            HasGenericParams::Yes,
                             Some((item.ident, constant_item_kind)),
                             |this| this.visit_expr(expr),
                         );
@@ -1909,20 +1920,23 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
     // Note that we intentionally still forbid `[0; N + 1]` during
     // name resolution so that we don't extend the future
     // compat lint to new cases.
+    #[instrument(level = "debug", skip(self, f))]
     fn with_constant_rib(
         &mut self,
         is_repeat: IsRepeatExpr,
-        is_trivial: bool,
+        may_use_generics: HasGenericParams,
         item: Option<(Ident, ConstantItemKind)>,
         f: impl FnOnce(&mut Self),
     ) {
-        debug!("with_constant_rib: is_repeat={:?} is_trivial={}", is_repeat, is_trivial);
-        self.with_rib(ValueNS, ConstantItemRibKind(is_trivial, item), |this| {
+        self.with_rib(ValueNS, ConstantItemRibKind(may_use_generics, item), |this| {
             this.with_rib(
                 TypeNS,
-                ConstantItemRibKind(is_repeat == IsRepeatExpr::Yes || is_trivial, item),
+                ConstantItemRibKind(
+                    may_use_generics.force_yes_if(is_repeat == IsRepeatExpr::Yes),
+                    item,
+                ),
                 |this| {
-                    this.with_label_rib(ConstantItemRibKind(is_trivial, item), f);
+                    this.with_label_rib(ConstantItemRibKind(may_use_generics, item), f);
                 },
             )
         });
@@ -2064,7 +2078,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                                                         // not used as part of the type system, this is far less surprising.
                                                         this.with_constant_rib(
                                                             IsRepeatExpr::No,
-                                                            true,
+                                                            HasGenericParams::Yes,
                                                             None,
                                                             |this| {
                                                                 visit::walk_assoc_item(
@@ -3077,7 +3091,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         debug!("resolve_anon_const {:?} is_repeat: {:?}", constant, is_repeat);
         self.with_constant_rib(
             is_repeat,
-            constant.value.is_potential_trivial_const_param(),
+            if constant.value.is_potential_trivial_const_param() {
+                HasGenericParams::Yes
+            } else {
+                HasGenericParams::No
+            },
             None,
             |this| visit::walk_anon_const(this, constant),
         );
@@ -3180,7 +3198,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     if const_args.contains(&idx) {
                         self.with_constant_rib(
                             IsRepeatExpr::No,
-                            argument.is_potential_trivial_const_param(),
+                            if argument.is_potential_trivial_const_param() {
+                                HasGenericParams::Yes
+                            } else {
+                                HasGenericParams::No
+                            },
                             None,
                             |this| {
                                 this.resolve_expr(argument, None);
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
index 616aa11f00a6b..75976ebdf2822 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
@@ -429,9 +429,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             errors.drain_filter(|error| {
                 let Error::Invalid(input_idx, Compatibility::Incompatible(error)) = error else { return false };
                 let expected_ty = expected_input_tys[*input_idx];
-                let provided_ty = final_arg_types[*input_idx].map(|ty| ty.0).unwrap();
+                let Some(Some((provided_ty, _))) = final_arg_types.get(*input_idx) else { return false };
                 let cause = &self.misc(provided_args[*input_idx].span);
-                let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
+                let trace = TypeTrace::types(cause, true, expected_ty, *provided_ty);
                 if let Some(e) = error {
                     if !matches!(trace.cause.as_failure_code(e), FailureCode::Error0308(_)) {
                         self.report_and_explain_type_error(trace, e).emit();
@@ -679,8 +679,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     Error::Invalid(input_idx, compatibility) => {
                         let expected_ty = expected_input_tys[input_idx];
                         if let Compatibility::Incompatible(error) = &compatibility {
-                            let provided_ty = final_arg_types[input_idx].map(|ty| ty.0).unwrap();
-                            let cause = &self.misc(provided_args[input_idx].span);
+                            let provided_ty = final_arg_types
+                                .get(input_idx)
+                                .and_then(|x| x.as_ref())
+                                .map(|ty| ty.0)
+                                .unwrap_or(tcx.ty_error());
+                            let cause = &self.misc(
+                                provided_args.get(input_idx).map(|i| i.span).unwrap_or(call_span),
+                            );
                             let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
                             if let Some(e) = error {
                                 self.note_type_err(
@@ -695,14 +701,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             }
                         }
 
-                        self.emit_coerce_suggestions(
-                            &mut err,
-                            &provided_args[input_idx],
-                            final_arg_types[input_idx].map(|ty| ty.0).unwrap(),
-                            final_arg_types[input_idx].map(|ty| ty.1).unwrap(),
-                            None,
-                            None,
-                        );
+                        if let Some(expr) = provided_args.get(input_idx) {
+                            self.emit_coerce_suggestions(
+                                &mut err,
+                                &expr,
+                                final_arg_types[input_idx].map(|ty| ty.0).unwrap(),
+                                final_arg_types[input_idx].map(|ty| ty.1).unwrap(),
+                                None,
+                                None,
+                            );
+                        }
                     }
                     Error::Extra(arg_idx) => {
                         let arg_type = if let Some((_, ty)) = final_arg_types[arg_idx] {
@@ -980,7 +988,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 );
                 for (idx, arg) in matched_inputs.iter().enumerate() {
                     let suggestion_text = if let Some(arg) = arg {
-                        let arg_span = provided_args[*arg].span;
+                        let arg_span = provided_args[*arg].span.source_callsite();
                         let arg_text = source_map.span_to_snippet(arg_span).unwrap();
                         arg_text
                     } else {
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 9e76af9829854..56a085c298250 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -1440,6 +1440,10 @@ fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> {
     let mut map = FxHashMap::default();
     // This is the list of IDs used in Javascript.
     map.insert("help".into(), 1);
+    map.insert("settings".into(), 1);
+    map.insert("not-displayed".into(), 1);
+    map.insert("alternative-display".into(), 1);
+    map.insert("search".into(), 1);
     // This is the list of IDs used in HTML generated in Rust (including the ones
     // used in tera template files).
     map.insert("mainThemeStyle".into(), 1);
@@ -1449,7 +1453,6 @@ fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> {
     map.insert("settings-menu".into(), 1);
     map.insert("help-button".into(), 1);
     map.insert("main-content".into(), 1);
-    map.insert("search".into(), 1);
     map.insert("crate-search".into(), 1);
     map.insert("render-detail".into(), 1);
     map.insert("toggle-all-docs".into(), 1);
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index 8e643107353dd..a30c533aa48c8 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -17,8 +17,8 @@ use super::print_item::{full_path, item_path, print_item};
 use super::search_index::build_index;
 use super::write_shared::write_shared;
 use super::{
-    collect_spans_and_sources, print_sidebar, scrape_examples_help, settings, AllTypes,
-    LinkFromSrc, NameDoc, StylePath, BASIC_KEYWORDS,
+    collect_spans_and_sources, print_sidebar, scrape_examples_help, AllTypes, LinkFromSrc, NameDoc,
+    StylePath, BASIC_KEYWORDS,
 };
 
 use crate::clean::{self, types::ExternalLocation, ExternalCrate};
@@ -589,21 +589,18 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
         page.root_path = "./";
 
         let sidebar = "<h2 class=\"location\">Settings</h2><div class=\"sidebar-elems\"></div>";
-        let theme_names: Vec<String> = self
-            .shared
-            .style_files
-            .iter()
-            .map(StylePath::basename)
-            .collect::<Result<_, Error>>()?;
         let v = layout::render(
             &self.shared.layout,
             &page,
             sidebar,
-            settings(
-                self.shared.static_root_path.as_deref().unwrap_or("./"),
-                &self.shared.resource_suffix,
-                theme_names,
-            )?,
+            |buf: &mut Buffer| {
+                write!(
+                    buf,
+                    "<script defer src=\"{}settings{}.js\"></script>",
+                    page.static_root_path.unwrap_or(""),
+                    page.resource_suffix
+                )
+            },
             &self.shared.style_files,
         );
         self.shared.fs.write(settings_file, v)?;
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 7a4289b8e60e9..fedeb449b2e0e 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -334,134 +334,6 @@ impl AllTypes {
     }
 }
 
-#[derive(Debug)]
-enum Setting {
-    Section {
-        description: &'static str,
-        sub_settings: Vec<Setting>,
-    },
-    Toggle {
-        js_data_name: &'static str,
-        description: &'static str,
-        default_value: bool,
-    },
-    Select {
-        js_data_name: &'static str,
-        description: &'static str,
-        default_value: &'static str,
-        options: Vec<String>,
-    },
-}
-
-impl Setting {
-    fn display(&self, root_path: &str, suffix: &str) -> String {
-        match *self {
-            Setting::Section { description, ref sub_settings } => format!(
-                "<div class=\"setting-line\">\
-                     <div class=\"title\">{}</div>\
-                     <div class=\"sub-settings\">{}</div>
-                 </div>",
-                description,
-                sub_settings.iter().map(|s| s.display(root_path, suffix)).collect::<String>()
-            ),
-            Setting::Toggle { js_data_name, description, default_value } => format!(
-                "<div class=\"setting-line\">\
-                     <label class=\"toggle\">\
-                     <input type=\"checkbox\" id=\"{}\" {}>\
-                     <span class=\"slider\"></span>\
-                     </label>\
-                     <div>{}</div>\
-                 </div>",
-                js_data_name,
-                if default_value { " checked" } else { "" },
-                description,
-            ),
-            Setting::Select { js_data_name, description, default_value, ref options } => format!(
-                "<div class=\"setting-line\"><div class=\"radio-line\" id=\"{}\"><span class=\"setting-name\">{}</span><div class=\"choices\">{}</div></div></div>",
-                js_data_name,
-                description,
-                options
-                    .iter()
-                    .map(|opt| format!(
-                        "<label for=\"{js_data_name}-{name}\" class=\"choice\">
-                           <input type=\"radio\" name=\"{js_data_name}\" id=\"{js_data_name}-{name}\" value=\"{name}\" {checked}>\
-                           {name}\
-                         </label>",
-                        js_data_name = js_data_name,
-                        name = opt,
-                        checked = if opt == default_value { "checked" } else { "" },
-                    ))
-                    .collect::<String>(),
-            ),
-        }
-    }
-}
-
-impl From<(&'static str, &'static str, bool)> for Setting {
-    fn from(values: (&'static str, &'static str, bool)) -> Setting {
-        Setting::Toggle { js_data_name: values.0, description: values.1, default_value: values.2 }
-    }
-}
-
-impl<T: Into<Setting>> From<(&'static str, Vec<T>)> for Setting {
-    fn from(values: (&'static str, Vec<T>)) -> Setting {
-        Setting::Section {
-            description: values.0,
-            sub_settings: values.1.into_iter().map(|v| v.into()).collect::<Vec<_>>(),
-        }
-    }
-}
-
-fn settings(root_path: &str, suffix: &str, theme_names: Vec<String>) -> Result<String, Error> {
-    // (id, explanation, default value)
-    let settings: &[Setting] = &[
-        Setting::from(("use-system-theme", "Use system theme", true)),
-        Setting::Select {
-            js_data_name: "theme",
-            description: "Theme",
-            default_value: "light",
-            options: theme_names.clone(),
-        },
-        Setting::Select {
-            js_data_name: "preferred-light-theme",
-            description: "Preferred light theme",
-            default_value: "light",
-            options: theme_names.clone(),
-        },
-        Setting::Select {
-            js_data_name: "preferred-dark-theme",
-            description: "Preferred dark theme",
-            default_value: "dark",
-            options: theme_names,
-        },
-        ("auto-hide-large-items", "Auto-hide item contents for large items.", true).into(),
-        ("auto-hide-method-docs", "Auto-hide item methods' documentation", false).into(),
-        ("auto-hide-trait-implementations", "Auto-hide trait implementation documentation", false)
-            .into(),
-        ("go-to-only-result", "Directly go to item in search if there is only one result", false)
-            .into(),
-        ("line-numbers", "Show line numbers on code examples", false).into(),
-        ("disable-shortcuts", "Disable keyboard shortcuts", false).into(),
-    ];
-
-    Ok(format!(
-        "<div class=\"main-heading\">
-            <h1 class=\"fqn\">\
-                <span class=\"in-band\">Rustdoc settings</span>\
-            </h1>\
-            <span class=\"out-of-band\">\
-            <a id=\"back\" href=\"javascript:void(0)\">Back</a>\
-            </span>\
-        </div>\
-        <div class=\"settings\">{}</div>\
-        <link rel=\"stylesheet\" href=\"{root_path}settings{suffix}.css\">\
-        <script src=\"{root_path}settings{suffix}.js\"></script>",
-        settings.iter().map(|s| s.display(root_path, suffix)).collect::<String>(),
-        root_path = root_path,
-        suffix = suffix
-    ))
-}
-
 fn scrape_examples_help(shared: &SharedContext<'_>) -> String {
     let mut content = SCRAPE_EXAMPLES_HELP_MD.to_owned();
     content.push_str(&format!(
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index 9e5de9a843ab1..f20061c65dd1b 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -57,11 +57,20 @@ function resourcePath(basename, extension) {
     return getVar("root-path") + basename + getVar("resource-suffix") + extension;
 }
 
+function hideMain() {
+    addClass(document.getElementById(MAIN_ID), "hidden");
+}
+
+function showMain() {
+    removeClass(document.getElementById(MAIN_ID), "hidden");
+}
+
 (function () {
     window.rootPath = getVar("root-path");
     window.currentCrate = getVar("current-crate");
     window.searchJS =  resourcePath("search", ".js");
     window.searchIndexJS = resourcePath("search-index", ".js");
+    window.settingsJS = resourcePath("settings", ".js");
     const sidebarVars = document.getElementById("sidebar-vars");
     if (sidebarVars) {
         window.sidebarCurrent = {
@@ -104,6 +113,9 @@ function getVirtualKey(ev) {
 const THEME_PICKER_ELEMENT_ID = "theme-picker";
 const THEMES_ELEMENT_ID = "theme-choices";
 const MAIN_ID = "main-content";
+const SETTINGS_BUTTON_ID = "settings-menu";
+const ALTERNATIVE_DISPLAY_ID = "alternative-display";
+const NOT_DISPLAYED_ID = "not-displayed";
 
 function getThemesElement() {
     return document.getElementById(THEMES_ELEMENT_ID);
@@ -113,6 +125,10 @@ function getThemePickerElement() {
     return document.getElementById(THEME_PICKER_ELEMENT_ID);
 }
 
+function getSettingsButton() {
+    return document.getElementById(SETTINGS_BUTTON_ID);
+}
+
 // Returns the current URL without any query parameter or hash.
 function getNakedUrl() {
     return window.location.href.split("?")[0].split("#")[0];
@@ -136,6 +152,10 @@ function hideThemeButtonState() {
     themePicker.style.borderBottomLeftRadius = "3px";
 }
 
+window.hideSettings = function() {
+    // Does nothing by default.
+};
+
 // Set up the theme picker list.
 (function () {
     if (!document.location.href.startsWith("file:///")) {
@@ -182,14 +202,120 @@ function hideThemeButtonState() {
     });
 }());
 
+/**
+ * This function inserts `newNode` after `referenceNode`. It doesn't work if `referenceNode`
+ * doesn't have a parent node.
+ *
+ * @param {HTMLElement} newNode
+ * @param {HTMLElement} referenceNode
+ */
+function insertAfter(newNode, referenceNode) {
+    referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
+}
+
+/**
+ * This function creates a new `<section>` with the given `id` and `classes` if it doesn't already
+ * exist.
+ *
+ * More information about this in `switchDisplayedElement` documentation.
+ *
+ * @param {string} id
+ * @param {string} classes
+ */
+function getOrCreateSection(id, classes) {
+    let el = document.getElementById(id);
+
+    if (!el) {
+        el = document.createElement("section");
+        el.id = id;
+        el.className = classes;
+        insertAfter(el, document.getElementById(MAIN_ID));
+    }
+    return el;
+}
+
+/**
+ * Returns the `<section>` element which contains the displayed element.
+ *
+ * @return {HTMLElement}
+ */
+function getAlternativeDisplayElem() {
+    return getOrCreateSection(ALTERNATIVE_DISPLAY_ID, "content hidden");
+}
+
+/**
+ * Returns the `<section>` element which contains the not-displayed elements.
+ *
+ * @return {HTMLElement}
+ */
+function getNotDisplayedElem() {
+    return getOrCreateSection(NOT_DISPLAYED_ID, "hidden");
+}
+
+/**
+ * To nicely switch between displayed "extra" elements (such as search results or settings menu)
+ * and to alternate between the displayed and not displayed elements, we hold them in two different
+ * `<section>` elements. They work in pair: one holds the hidden elements while the other
+ * contains the displayed element (there can be only one at the same time!). So basically, we switch
+ * elements between the two `<section>` elements.
+ *
+ * @param {HTMLElement} elemToDisplay
+ */
+function switchDisplayedElement(elemToDisplay) {
+    const el = getAlternativeDisplayElem();
+
+    if (el.children.length > 0) {
+        getNotDisplayedElem().appendChild(el.firstElementChild);
+    }
+    if (elemToDisplay === null) {
+        addClass(el, "hidden");
+        showMain();
+        return;
+    }
+    el.appendChild(elemToDisplay);
+    hideMain();
+    removeClass(el, "hidden");
+}
+
+function browserSupportsHistoryApi() {
+    return window.history && typeof window.history.pushState === "function";
+}
+
+// eslint-disable-next-line no-unused-vars
+function loadCss(cssFileName) {
+    const link = document.createElement("link");
+    link.href = resourcePath(cssFileName, ".css");
+    link.type = "text/css";
+    link.rel = "stylesheet";
+    document.getElementsByTagName("head")[0].appendChild(link);
+}
+
 (function() {
     "use strict";
 
+    function loadScript(url) {
+        const script = document.createElement('script');
+        script.src = url;
+        document.head.append(script);
+    }
+
+
+    getSettingsButton().onclick = function(event) {
+        event.preventDefault();
+        loadScript(window.settingsJS);
+    };
+
     window.searchState = {
         loadingText: "Loading search results...",
         input: document.getElementsByClassName("search-input")[0],
         outputElement: function() {
-            return document.getElementById("search");
+            let el = document.getElementById("search");
+            if (!el) {
+                el = document.createElement("section");
+                el.id = "search";
+                getNotDisplayedElem().appendChild(el);
+            }
+            return el;
         },
         title: document.title,
         titleBeforeSearch: document.title,
@@ -208,6 +334,9 @@ function hideThemeButtonState() {
                 searchState.timeout = null;
             }
         },
+        isDisplayed: function() {
+            return searchState.outputElement().parentElement.id === ALTERNATIVE_DISPLAY_ID;
+        },
         // Sets the focus on the search bar at the top of the page
         focus: function() {
             searchState.input.focus();
@@ -220,20 +349,15 @@ function hideThemeButtonState() {
             if (search === null || typeof search === 'undefined') {
                 search = searchState.outputElement();
             }
-            addClass(main, "hidden");
-            removeClass(search, "hidden");
+            switchDisplayedElement(search);
             searchState.mouseMovedAfterSearch = false;
             document.title = searchState.title;
         },
-        hideResults: function(search) {
-            if (search === null || typeof search === 'undefined') {
-                search = searchState.outputElement();
-            }
-            addClass(search, "hidden");
-            removeClass(main, "hidden");
+        hideResults: function() {
+            switchDisplayedElement(null);
             document.title = searchState.titleBeforeSearch;
             // We also remove the query parameter from the URL.
-            if (searchState.browserSupportsHistoryApi()) {
+            if (browserSupportsHistoryApi()) {
                 history.replaceState(null, window.currentCrate + " - Rust",
                     getNakedUrl() + window.location.hash);
             }
@@ -248,20 +372,11 @@ function hideThemeButtonState() {
                 });
             return params;
         },
-        browserSupportsHistoryApi: function() {
-            return window.history && typeof window.history.pushState === "function";
-        },
         setup: function() {
             const search_input = searchState.input;
             if (!searchState.input) {
                 return;
             }
-            function loadScript(url) {
-                const script = document.createElement('script');
-                script.src = url;
-                document.head.append(script);
-            }
-
             let searchLoaded = false;
             function loadSearch() {
                 if (!searchLoaded) {
@@ -303,23 +418,20 @@ function hideThemeButtonState() {
     }
 
     const toggleAllDocsId = "toggle-all-docs";
-    const main = document.getElementById(MAIN_ID);
     let savedHash = "";
 
     function handleHashes(ev) {
-        let elem;
-        const search = searchState.outputElement();
-        if (ev !== null && search && !hasClass(search, "hidden") && ev.newURL) {
+        if (ev !== null && searchState.isDisplayed() && ev.newURL) {
             // This block occurs when clicking on an element in the navbar while
             // in a search.
-            searchState.hideResults(search);
+            switchDisplayedElement(null);
             const hash = ev.newURL.slice(ev.newURL.indexOf("#") + 1);
-            if (searchState.browserSupportsHistoryApi()) {
+            if (browserSupportsHistoryApi()) {
                 // `window.location.search`` contains all the query parameters, not just `search`.
                 history.replaceState(null, "",
                     getNakedUrl() + window.location.search + "#" + hash);
             }
-            elem = document.getElementById(hash);
+            const elem = document.getElementById(hash);
             if (elem) {
                 elem.scrollIntoView();
             }
@@ -389,14 +501,17 @@ function hideThemeButtonState() {
     }
 
     function handleEscape(ev) {
+        searchState.clearInputTimeout();
         const help = getHelpElement(false);
-        const search = searchState.outputElement();
         if (help && !hasClass(help, "hidden")) {
             displayHelp(false, ev, help);
-        } else if (search && !hasClass(search, "hidden")) {
-            searchState.clearInputTimeout();
+        } else {
+            switchDisplayedElement(null);
+            if (browserSupportsHistoryApi()) {
+                history.replaceState(null, window.currentCrate + " - Rust",
+                    getNakedUrl() + window.location.hash);
+            }
             ev.preventDefault();
-            searchState.hideResults(search);
         }
         searchState.defocus();
         hideThemeButtonState();
@@ -733,10 +848,6 @@ function hideThemeButtonState() {
         innerToggle.children[0].innerText = labelForToggleButton(sectionIsCollapsed);
     }
 
-    function insertAfter(newNode, referenceNode) {
-        referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
-    }
-
     (function() {
         const toggles = document.getElementById(toggleAllDocsId);
         if (toggles) {
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index a6f7dd74af6b0..84600fa3e094f 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -2,7 +2,7 @@
 /* eslint no-var: "error" */
 /* eslint prefer-const: "error" */
 /* global addClass, getNakedUrl, getSettingValue, hasOwnPropertyRustdoc, initSearch, onEach */
-/* global onEachLazy, removeClass, searchState, hasClass */
+/* global onEachLazy, removeClass, searchState, browserSupportsHistoryApi */
 
 (function() {
 // This mapping table should match the discriminants of
@@ -1786,8 +1786,9 @@ window.initSearch = function(rawSearchIndex) {
 
         // Because searching is incremental by character, only the most
         // recent search query is added to the browser history.
-        if (searchState.browserSupportsHistoryApi()) {
+        if (browserSupportsHistoryApi()) {
             const newURL = buildUrl(query.original, filterCrates);
+
             if (!history.state && !params.search) {
                 history.pushState(null, "", newURL);
             } else {
@@ -1965,10 +1966,9 @@ window.initSearch = function(rawSearchIndex) {
         if (!searchState.input) {
             return;
         }
-        const search = searchState.outputElement();
-        if (search_input.value !== "" && hasClass(search, "hidden")) {
-            searchState.showResults(search);
-            if (searchState.browserSupportsHistoryApi()) {
+        if (search_input.value !== "" && !searchState.isDisplayed()) {
+            searchState.showResults();
+            if (browserSupportsHistoryApi()) {
                 history.replaceState(null, "",
                     buildUrl(search_input.value, getFilterCrates()));
             }
@@ -1980,7 +1980,7 @@ window.initSearch = function(rawSearchIndex) {
         const searchAfter500ms = function() {
             searchState.clearInputTimeout();
             if (searchState.input.value.length === 0) {
-                if (searchState.browserSupportsHistoryApi()) {
+                if (browserSupportsHistoryApi()) {
                     history.replaceState(null, window.currentCrate + " - Rust",
                         getNakedUrl() + window.location.hash);
                 }
@@ -2058,7 +2058,7 @@ window.initSearch = function(rawSearchIndex) {
 
         // Push and pop states are used to add search results to the browser
         // history.
-        if (searchState.browserSupportsHistoryApi()) {
+        if (browserSupportsHistoryApi()) {
             // Store the previous <title> so we can revert back to it later.
             const previousTitle = document.title;
 
diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js
index 7bc6f6cfe043d..a2f8d56fb320b 100644
--- a/src/librustdoc/html/static/js/settings.js
+++ b/src/librustdoc/html/static/js/settings.js
@@ -2,10 +2,13 @@
 /* eslint no-var: "error" */
 /* eslint prefer-const: "error" */
 // Local js definitions:
-/* global getSettingValue, getVirtualKey, onEachLazy, updateLocalStorage, updateSystemTheme */
-/* global addClass, removeClass */
+/* global getSettingValue, getVirtualKey, updateLocalStorage, updateSystemTheme, loadCss */
+/* global addClass, removeClass, onEach, onEachLazy, NOT_DISPLAYED_ID */
+/* global MAIN_ID, getVar, getSettingsButton, switchDisplayedElement, getNotDisplayedElem */
 
 (function () {
+    const isSettingsPage = window.location.pathname.endsWith("/settings.html");
+
     function changeSetting(settingName, value) {
         updateLocalStorage(settingName, value);
 
@@ -55,9 +58,9 @@
         }
     }
 
-    function setEvents() {
+    function setEvents(settingsElement) {
         updateLightAndDark();
-        onEachLazy(document.getElementsByClassName("slider"), function(elem) {
+        onEachLazy(settingsElement.getElementsByClassName("slider"), function(elem) {
             const toggle = elem.previousElementSibling;
             const settingId = toggle.id;
             const settingValue = getSettingValue(settingId);
@@ -70,7 +73,7 @@
             toggle.onkeyup = handleKey;
             toggle.onkeyrelease = handleKey;
         });
-        onEachLazy(document.getElementsByClassName("select-wrapper"), function(elem) {
+        onEachLazy(settingsElement.getElementsByClassName("select-wrapper"), function(elem) {
             const select = elem.getElementsByTagName("select")[0];
             const settingId = select.id;
             const settingValue = getSettingValue(settingId);
@@ -81,7 +84,7 @@
                 changeSetting(this.id, this.value);
             };
         });
-        onEachLazy(document.querySelectorAll("input[type=\"radio\"]"), function(elem) {
+        onEachLazy(settingsElement.querySelectorAll("input[type=\"radio\"]"), function(elem) {
             const settingId = elem.name;
             const settingValue = getSettingValue(settingId);
             if (settingValue !== null && settingValue !== "null") {
@@ -91,10 +94,182 @@
                 changeSetting(ev.target.name, ev.target.value);
             });
         });
-        document.getElementById("back").addEventListener("click", function() {
-            history.back();
-        });
     }
 
-    window.addEventListener("DOMContentLoaded", setEvents);
+    /**
+     * This function builds the sections inside the "settings page". It takes a `settings` list
+     * as argument which describes each setting and how to render it. It returns a string
+     * representing the raw HTML.
+     *
+     * @param {Array<Object>} settings
+     *
+     * @return {string}
+     */
+    function buildSettingsPageSections(settings) {
+        let output = "";
+
+        for (const setting of settings) {
+            output += `<div class="setting-line">`;
+            const js_data_name = setting["js_name"];
+            const setting_name = setting["name"];
+
+            if (setting["options"] !== undefined) {
+                // This is a select setting.
+                output += `<div class="radio-line" id="${js_data_name}">\
+                        <span class="setting-name">${setting_name}</span>\
+                        <div class="choices">`;
+                onEach(setting["options"], function(option) {
+                    const checked = option === setting["default"] ? " checked" : "";
+
+                    output += `<label for="${js_data_name}-${option}" class="choice">\
+                           <input type="radio" name="${js_data_name}" \
+                                id="${js_data_name}-${option}" value="${option}"${checked}>\
+                           ${option}\
+                         </label>`;
+                });
+                output += "</div></div>";
+            } else {
+                // This is a toggle.
+                const checked = setting["default"] === true ? " checked" : "";
+                output += `
+                    <label class="toggle">
+                        <input type="checkbox" id="${js_data_name}"${checked}>
+                        <span class="slider"></span>
+                    </label>
+                    <div>${setting_name}</div>`;
+            }
+            output += "</div>";
+        }
+        return output;
+    }
+
+    /**
+     * This function builds the "settings page" and returns the generated HTML element.
+     *
+     * @return {HTMLElement}
+     */
+    function buildSettingsPage() {
+        const themes = getVar("themes").split(",");
+        const settings = [
+            {
+                "name": "Use system theme",
+                "js_name": "use-system-theme",
+                "default": true,
+            },
+            {
+                "name": "Theme",
+                "js_name": "theme",
+                "default": "light",
+                "options": themes,
+            },
+            {
+                "name": "Preferred light theme",
+                "js_name": "preferred-light-theme",
+                "default": "light",
+                "options": themes,
+            },
+            {
+                "name": "Preferred dark theme",
+                "js_name": "preferred-dark-theme",
+                "default": "dark",
+                "options": themes,
+            },
+            {
+                "name": "Auto-hide item contents for large items",
+                "js_name": "auto-hide-large-items",
+                "default": true,
+            },
+            {
+                "name": "Auto-hide item methods' documentation",
+                "js_name": "auto-hide-method-docs",
+                "default": false,
+            },
+            {
+                "name": "Auto-hide trait implementation documentation",
+                "js_name": "auto-hide-trait-implementations",
+                "default": false,
+            },
+            {
+                "name": "Directly go to item in search if there is only one result",
+                "js_name": "go-to-only-result",
+                "default": false,
+            },
+            {
+                "name": "Show line numbers on code examples",
+                "js_name": "line-numbers",
+                "default": false,
+            },
+            {
+                "name": "Disable keyboard shortcuts",
+                "js_name": "disable-shortcuts",
+                "default": false,
+            },
+        ];
+
+        // First, we add the settings.css file.
+        loadCss("settings");
+
+        // Then we build the DOM.
+        const el = document.createElement("section");
+        el.id = "settings";
+        let innerHTML = `
+            <div class="main-heading">
+                <h1 class="fqn">
+                    <span class="in-band">Rustdoc settings</span>
+                </h1>
+                <span class="out-of-band">`;
+
+        if (isSettingsPage) {
+            innerHTML +=
+                `<a id="back" href="javascript:void(0)" onclick="history.back();">Back</a>`;
+        } else {
+            innerHTML +=
+                `<a id="back" href="javascript:void(0)" onclick="switchDisplayedElement(null);">\
+                    Back</a>`;
+        }
+        innerHTML += `</span>
+            </div>
+            <div class="settings">${buildSettingsPageSections(settings)}</div>`;
+
+        el.innerHTML = innerHTML;
+
+        if (isSettingsPage) {
+            document.getElementById(MAIN_ID).appendChild(el);
+        } else {
+            getNotDisplayedElem().appendChild(el);
+        }
+        return el;
+    }
+
+    const settingsMenu = buildSettingsPage();
+
+    if (isSettingsPage) {
+        // We replace the existing "onclick" callback to do nothing if clicked.
+        getSettingsButton().onclick = function(event) {
+            event.preventDefault();
+        };
+    } else {
+        // We replace the existing "onclick" callback.
+        const settingsButton = getSettingsButton();
+        settingsButton.onclick = function(event) {
+            event.preventDefault();
+            if (settingsMenu.parentElement.id === NOT_DISPLAYED_ID) {
+                switchDisplayedElement(settingsMenu);
+            } else {
+                window.hideSettings();
+            }
+        };
+        window.hideSettings = function() {
+            switchDisplayedElement(null);
+        };
+    }
+
+    // We now wait a bit for the web browser to end re-computing the DOM...
+    setTimeout(function() {
+        setEvents(settingsMenu);
+        // The setting menu is already displayed if we're on the settings page.
+        if (!isSettingsPage) {
+            switchDisplayedElement(settingsMenu);
+        }
+    }, 0);
 })();
diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js
index c48a847665ef5..6aee0da69f8de 100644
--- a/src/librustdoc/html/static/js/source-script.js
+++ b/src/librustdoc/html/static/js/source-script.js
@@ -6,7 +6,7 @@
 /* global search, sourcesIndex */
 
 // Local js definitions:
-/* global addClass, getCurrentValue, hasClass, onEachLazy, removeClass, searchState */
+/* global addClass, getCurrentValue, hasClass, onEachLazy, removeClass, browserSupportsHistoryApi */
 /* global updateLocalStorage */
 (function() {
 
@@ -195,7 +195,7 @@ const handleSourceHighlight = (function() {
     const set_fragment = function(name) {
         const x = window.scrollX,
             y = window.scrollY;
-        if (searchState.browserSupportsHistoryApi()) {
+        if (browserSupportsHistoryApi()) {
             history.replaceState(null, null, "#" + name);
             highlightSourceLines();
         } else {
diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html
index 564731ab7354b..470cce93a5020 100644
--- a/src/librustdoc/html/templates/page.html
+++ b/src/librustdoc/html/templates/page.html
@@ -135,7 +135,6 @@ <h2 class="location"></h2>
                 </nav> {#- -#}
             </div> {#- -#}
             <section id="main-content" class="content">{{- content|safe -}}</section> {#- -#}
-            <section id="search" class="content hidden"></section> {#- -#}
         </div> {#- -#}
     </main> {#- -#}
     {{- layout.external_html.after_content|safe -}}
diff --git a/src/test/rustdoc-gui/escape-key.goml b/src/test/rustdoc-gui/escape-key.goml
index 6e305e81eeec0..8713bf65c8432 100644
--- a/src/test/rustdoc-gui/escape-key.goml
+++ b/src/test/rustdoc-gui/escape-key.goml
@@ -4,17 +4,20 @@ goto: file://|DOC_PATH|/test_docs/index.html
 // First, we check that the search results are hidden when the Escape key is pressed.
 write: (".search-input", "test")
 wait-for: "#search h1" // The search element is empty before the first search 
-assert-attribute: ("#search", {"class": "content"})
+// Check that the currently displayed element is search.
+wait-for: "#alternative-display #search"
 assert-attribute: ("#main-content", {"class": "content hidden"})
 assert-document-property: ({"URL": "index.html?search=test"}, ENDS_WITH)
 press-key: "Escape"
-assert-attribute: ("#search", {"class": "content hidden"})
+// Checks that search is no longer in the displayed content.
+wait-for: "#not-displayed #search"
+assert-false: "#alternative-display #search"
 assert-attribute: ("#main-content", {"class": "content"})
 assert-document-property: ({"URL": "index.html"}, [ENDS_WITH])
 
 // Check that focusing the search input brings back the search results
 focus: ".search-input"
-assert-attribute: ("#search", {"class": "content"})
+wait-for: "#alternative-display #search"
 assert-attribute: ("#main-content", {"class": "content hidden"})
 assert-document-property: ({"URL": "index.html?search=test"}, ENDS_WITH)
 
@@ -24,8 +27,8 @@ click: "#help-button"
 assert-document-property: ({"URL": "index.html?search=test"}, [ENDS_WITH])
 assert-attribute: ("#help", {"class": ""})
 press-key: "Escape"
+wait-for: "#alternative-display #search"
 assert-attribute: ("#help", {"class": "hidden"})
-assert-attribute: ("#search", {"class": "content"})
 assert-attribute: ("#main-content", {"class": "content hidden"})
 assert-document-property: ({"URL": "index.html?search=test"}, [ENDS_WITH])
 
@@ -37,5 +40,6 @@ assert-false: ".search-input:focus"
 assert: "#results a:focus"
 press-key: "Escape"
 assert-attribute: ("#help", {"class": "hidden"})
-assert-attribute: ("#search", {"class": "content hidden"})
+wait-for: "#not-displayed #search"
+assert-false: "#alternative-display #search"
 assert-attribute: ("#main-content", {"class": "content"})
diff --git a/src/test/rustdoc-gui/settings.goml b/src/test/rustdoc-gui/settings.goml
new file mode 100644
index 0000000000000..6c4611b1cb2a6
--- /dev/null
+++ b/src/test/rustdoc-gui/settings.goml
@@ -0,0 +1,67 @@
+// This test ensures that the settings menu display is working as expected.
+goto: file://|DOC_PATH|/test_docs/index.html
+// First, we check that the settings page doesn't exist.
+assert-false: "#settings"
+// We now click on the settings button.
+click: "#settings-menu"
+wait-for: "#settings"
+assert: "#main-content.hidden"
+assert-css: ("#settings", {"display": "block"})
+// Let's close it by clicking on the same button.
+click: "#settings-menu"
+assert-false: "#alternative-display #settings"
+assert: "#not-displayed #settings"
+assert: "#main-content:not(.hidden)"
+
+// Let's open and then close it again with the "close settings" button.
+click: "#settings-menu"
+wait-for: "#alternative-display #settings"
+assert: "#main-content.hidden"
+click: "#back"
+wait-for: "#not-displayed #settings"
+assert: "#main-content:not(.hidden)"
+
+// Let's check that pressing "ESCAPE" is closing it.
+click: "#settings-menu"
+wait-for: "#alternative-display #settings"
+press-key: "Escape"
+wait-for: "#not-displayed #settings"
+assert: "#main-content:not(.hidden)"
+
+// Let's click on it when the search results are displayed.
+focus: ".search-input"
+write: "test"
+wait-for: "#alternative-display #search"
+click: "#settings-menu"
+wait-for: "#alternative-display #settings"
+assert: "#not-displayed #search"
+assert: "#main-content.hidden"
+
+// Now let's check the content of the settings menu.
+local-storage: {"rustdoc-theme": "dark", "rustdoc-use-system-theme": "false"}
+reload:
+click: "#settings-menu"
+wait-for: "#settings"
+
+// We check that the "Use system theme" is disabled.
+assert-property: ("#use-system-theme", {"checked": "false"})
+assert: "//*[@class='setting-line']/*[text()='Use system theme']"
+// Meaning that only the "theme" menu is showing up.
+assert: ".setting-line:not(.hidden) #theme"
+assert: ".setting-line.hidden #preferred-dark-theme"
+assert: ".setting-line.hidden #preferred-light-theme"
+
+// We check that the correct theme is selected.
+assert-property: ("#theme .choices #theme-dark", {"checked": "true"})
+
+// We now switch the display.
+click: "#use-system-theme"
+// Wait for the hidden element to show up.
+wait-for: ".setting-line:not(.hidden) #preferred-dark-theme"
+assert: ".setting-line:not(.hidden) #preferred-light-theme"
+// Check that the theme picking is hidden.
+assert: ".setting-line.hidden #theme"
+
+// We check their text as well.
+assert-text: ("#preferred-dark-theme .setting-name", "Preferred dark theme")
+assert-text: ("#preferred-light-theme .setting-name", "Preferred light theme")
diff --git a/src/test/rustdoc-gui/theme-change.goml b/src/test/rustdoc-gui/theme-change.goml
index 333391ba27970..9706511ea19c3 100644
--- a/src/test/rustdoc-gui/theme-change.goml
+++ b/src/test/rustdoc-gui/theme-change.goml
@@ -9,6 +9,7 @@ click: "#theme-choices > button:last-child"
 wait-for-css: ("body", { "background-color": "rgb(255, 255, 255)" })
 
 goto: file://|DOC_PATH|/settings.html
+wait-for: "#settings"
 click: "#theme-light"
 wait-for-css: ("body", { "background-color": "rgb(255, 255, 255)" })
 assert-local-storage: { "rustdoc-theme": "light" }
diff --git a/src/test/rustdoc-gui/theme-in-history.goml b/src/test/rustdoc-gui/theme-in-history.goml
index 3b66c85d8dad2..f576ced1c6208 100644
--- a/src/test/rustdoc-gui/theme-in-history.goml
+++ b/src/test/rustdoc-gui/theme-in-history.goml
@@ -1,15 +1,19 @@
 // Ensures that the theme is working when going back in history.
 goto: file://|DOC_PATH|/test_docs/index.html
 // Set the theme to dark.
-local-storage: {"rustdoc-theme": "dark", "rustdoc-preferred-dark-theme": "dark", "rustdoc-use-system-theme": "false"}
+local-storage: {
+    "rustdoc-theme": "dark",
+    "rustdoc-preferred-dark-theme": "dark",
+    "rustdoc-use-system-theme": "false",
+}
 // We reload the page so the local storage settings are being used.
 reload:
 assert-css: ("body", { "background-color": "rgb(53, 53, 53)" })
 assert-local-storage: { "rustdoc-theme": "dark" }
 
 // Now we go to the settings page.
-click: "#settings-menu"
-wait-for: ".settings"
+goto: file://|DOC_PATH|/settings.html
+wait-for: "#settings"
 // We change the theme to "light".
 click: "#theme-light"
 wait-for-css: ("body", { "background-color": "rgb(255, 255, 255)" })
@@ -18,7 +22,7 @@ assert-local-storage: { "rustdoc-theme": "light" }
 // We go back in history.
 history-go-back:
 // Confirm that we're not on the settings page.
-assert-false: ".settings"
+assert-false: "#settings"
 // Check that the current theme is still "light".
 assert-css: ("body", { "background-color": "rgb(255, 255, 255)" })
 assert-local-storage: { "rustdoc-theme": "light" }
diff --git a/src/test/ui/argument-suggestions/issue-96638.rs b/src/test/ui/argument-suggestions/issue-96638.rs
new file mode 100644
index 0000000000000..9c6e81ab8cc75
--- /dev/null
+++ b/src/test/ui/argument-suggestions/issue-96638.rs
@@ -0,0 +1,9 @@
+fn f(_: usize, _: &usize, _: usize) {}
+
+fn arg<T>() -> T { todo!() }
+
+fn main() {
+    let x = arg(); // `x` must be inferred
+    // The reference on `&x` is important to reproduce the ICE
+    f(&x, ""); //~ ERROR this function takes 3 arguments but 2 arguments were supplied
+}
diff --git a/src/test/ui/argument-suggestions/issue-96638.stderr b/src/test/ui/argument-suggestions/issue-96638.stderr
new file mode 100644
index 0000000000000..35190e2ca0d82
--- /dev/null
+++ b/src/test/ui/argument-suggestions/issue-96638.stderr
@@ -0,0 +1,19 @@
+error[E0061]: this function takes 3 arguments but 2 arguments were supplied
+  --> $DIR/issue-96638.rs:8:5
+   |
+LL |     f(&x, "");
+   |     ^ -- an argument of type `usize` is missing
+   |
+note: function defined here
+  --> $DIR/issue-96638.rs:1:4
+   |
+LL | fn f(_: usize, _: &usize, _: usize) {}
+   |    ^ --------  ---------  --------
+help: provide the argument
+   |
+LL |     f({usize}, &x, {usize});
+   |     ~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0061`.
diff --git a/src/test/ui/async-await/no-async-const.stderr b/src/test/ui/async-await/no-async-const.stderr
index ae13b90c3cfc0..a51dc88a4eded 100644
--- a/src/test/ui/async-await/no-async-const.stderr
+++ b/src/test/ui/async-await/no-async-const.stderr
@@ -7,7 +7,7 @@ LL | pub async const fn x() {}
    |     |     expected one of `extern`, `fn`, or `unsafe`
    |     help: `const` must come before `async`: `const async`
    |
-   = note: keyword order for functions declaration is `default`, `pub`, `const`, `async`, `unsafe`, `extern`
+   = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/async-await/no-unsafe-async.stderr b/src/test/ui/async-await/no-unsafe-async.stderr
index 0c362052501ed..f23d17d6bfa57 100644
--- a/src/test/ui/async-await/no-unsafe-async.stderr
+++ b/src/test/ui/async-await/no-unsafe-async.stderr
@@ -12,7 +12,7 @@ LL |     unsafe async fn g() {}
 LL | }
    | - the item list ends here
    |
-   = note: keyword order for functions declaration is `default`, `pub`, `const`, `async`, `unsafe`, `extern`
+   = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
 
 error: expected one of `extern` or `fn`, found keyword `async`
   --> $DIR/no-unsafe-async.rs:11:8
@@ -23,7 +23,7 @@ LL | unsafe async fn f() {}
    | |      expected one of `extern` or `fn`
    | help: `async` must come before `unsafe`: `async unsafe`
    |
-   = note: keyword order for functions declaration is `default`, `pub`, `const`, `async`, `unsafe`, `extern`
+   = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/fn/keyword-order.rs b/src/test/ui/fn/keyword-order.rs
new file mode 100644
index 0000000000000..8a21db6733352
--- /dev/null
+++ b/src/test/ui/fn/keyword-order.rs
@@ -0,0 +1,6 @@
+// edition:2018
+
+default pub const async unsafe extern fn err() {} //~ ERROR `default` is not followed by an item
+//~^ ERROR expected item, found keyword `pub`
+
+pub default const async unsafe extern fn ok() {}
diff --git a/src/test/ui/fn/keyword-order.stderr b/src/test/ui/fn/keyword-order.stderr
new file mode 100644
index 0000000000000..d3b140c852860
--- /dev/null
+++ b/src/test/ui/fn/keyword-order.stderr
@@ -0,0 +1,16 @@
+error: `default` is not followed by an item
+  --> $DIR/keyword-order.rs:3:1
+   |
+LL | default pub const async unsafe extern fn err() {}
+   | ^^^^^^^ the `default` qualifier
+   |
+   = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default`
+
+error: expected item, found keyword `pub`
+  --> $DIR/keyword-order.rs:3:9
+   |
+LL | default pub const async unsafe extern fn err() {}
+   |         ^^^ expected item
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/impl-trait/issues/issue-92305.rs b/src/test/ui/impl-trait/issues/issue-92305.rs
new file mode 100644
index 0000000000000..1518c116b3185
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-92305.rs
@@ -0,0 +1,15 @@
+// edition:2021
+
+use std::iter;
+
+fn f<T>(data: &[T]) -> impl Iterator<Item = Vec> {
+    //~^ ERROR: missing generics for struct `Vec` [E0107]
+    iter::empty() //~ ERROR: type annotations needed [E0282]
+}
+
+fn g<T>(data: &[T], target: T) -> impl Iterator<Item = Vec<T>> {
+    //~^ ERROR: type annotations needed [E0282]
+    f(data).filter(|x| x == target)
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/issues/issue-92305.stderr b/src/test/ui/impl-trait/issues/issue-92305.stderr
new file mode 100644
index 0000000000000..c4fc49225e9a0
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-92305.stderr
@@ -0,0 +1,32 @@
+error[E0107]: missing generics for struct `Vec`
+  --> $DIR/issue-92305.rs:5:45
+   |
+LL | fn f<T>(data: &[T]) -> impl Iterator<Item = Vec> {
+   |                                             ^^^ expected at least 1 generic argument
+   |
+note: struct defined here, with at least 1 generic parameter: `T`
+  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+   |
+LL | pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> {
+   |            ^^^ -
+help: add missing generic argument
+   |
+LL | fn f<T>(data: &[T]) -> impl Iterator<Item = Vec<T>> {
+   |                                             ~~~~~~
+
+error[E0282]: type annotations needed
+  --> $DIR/issue-92305.rs:7:5
+   |
+LL |     iter::empty()
+   |     ^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the function `empty`
+
+error[E0282]: type annotations needed
+  --> $DIR/issue-92305.rs:10:35
+   |
+LL | fn g<T>(data: &[T], target: T) -> impl Iterator<Item = Vec<T>> {
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0107, E0282.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/src/test/ui/parser/issues/issue-19398.stderr b/src/test/ui/parser/issues/issue-19398.stderr
index f9c3ca763f26e..bbd85374b4bcf 100644
--- a/src/test/ui/parser/issues/issue-19398.stderr
+++ b/src/test/ui/parser/issues/issue-19398.stderr
@@ -12,7 +12,7 @@ LL |
 LL | }
    | - the item list ends here
    |
-   = note: keyword order for functions declaration is `default`, `pub`, `const`, `async`, `unsafe`, `extern`
+   = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs b/src/test/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs
index 86fdb78cce8ab..bbebc99e94b82 100644
--- a/src/test/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs
+++ b/src/test/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs
@@ -11,4 +11,4 @@ async unsafe const fn test() {}
 //~| NOTE expected one of `extern` or `fn`
 //~| HELP `const` must come before `async unsafe`
 //~| SUGGESTION const async unsafe
-//~| NOTE keyword order for functions declaration is `default`, `pub`, `const`, `async`, `unsafe`, `extern`
+//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.stderr b/src/test/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.stderr
index 65cce77be896b..f455caba158c7 100644
--- a/src/test/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.stderr
+++ b/src/test/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.stderr
@@ -7,7 +7,7 @@ LL | async unsafe const fn test() {}
    | |            expected one of `extern` or `fn`
    | help: `const` must come before `async unsafe`: `const async unsafe`
    |
-   = note: keyword order for functions declaration is `default`, `pub`, `const`, `async`, `unsafe`, `extern`
+   = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-async.rs b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-async.rs
index edfb330d6713a..4ff4cf5c8ca87 100644
--- a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-async.rs
+++ b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-async.rs
@@ -11,4 +11,4 @@ unsafe async fn test() {}
 //~| NOTE expected one of `extern` or `fn`
 //~| HELP `async` must come before `unsafe`
 //~| SUGGESTION async unsafe
-//~| NOTE keyword order for functions declaration is `default`, `pub`, `const`, `async`, `unsafe`, `extern`
+//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-async.stderr b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-async.stderr
index 3acd9e4400432..e9eb14bf00e77 100644
--- a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-async.stderr
+++ b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-async.stderr
@@ -7,7 +7,7 @@ LL | unsafe async fn test() {}
    | |      expected one of `extern` or `fn`
    | help: `async` must come before `unsafe`: `async unsafe`
    |
-   = note: keyword order for functions declaration is `default`, `pub`, `const`, `async`, `unsafe`, `extern`
+   = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-const.rs b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-const.rs
index abd692b80d54b..2f5fbc513ee36 100644
--- a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-const.rs
+++ b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-const.rs
@@ -11,4 +11,4 @@ unsafe const fn test() {}
 //~| NOTE expected one of `extern` or `fn`
 //~| HELP `const` must come before `unsafe`
 //~| SUGGESTION const unsafe
-//~| NOTE keyword order for functions declaration is `default`, `pub`, `const`, `async`, `unsafe`, `extern`
+//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-const.stderr b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-const.stderr
index 9a3e07b1e87f6..0d2bc3472965f 100644
--- a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-const.stderr
+++ b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-const.stderr
@@ -7,7 +7,7 @@ LL | unsafe const fn test() {}
    | |      expected one of `extern` or `fn`
    | help: `const` must come before `unsafe`: `const unsafe`
    |
-   = note: keyword order for functions declaration is `default`, `pub`, `const`, `async`, `unsafe`, `extern`
+   = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.rs b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.rs
index 7f0761e99386a..df2412e3e9b32 100644
--- a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.rs
+++ b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.rs
@@ -11,4 +11,4 @@ extern unsafe fn test() {}
 //~| NOTE expected `fn`
 //~| HELP `unsafe` must come before `extern`
 //~| SUGGESTION unsafe extern
-//~| NOTE keyword order for functions declaration is `default`, `pub`, `const`, `async`, `unsafe`, `extern`
+//~| NOTE keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
diff --git a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr
index 395ee9fedbc07..4224713ccb53a 100644
--- a/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr
+++ b/src/test/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr
@@ -7,7 +7,7 @@ LL | extern unsafe fn test() {}
    | |      expected `fn`
    | help: `unsafe` must come before `extern`: `unsafe extern`
    |
-   = note: keyword order for functions declaration is `default`, `pub`, `const`, `async`, `unsafe`, `extern`
+   = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/typeck/remove-extra-argument.fixed b/src/test/ui/typeck/remove-extra-argument.fixed
new file mode 100644
index 0000000000000..a9338c76cdc88
--- /dev/null
+++ b/src/test/ui/typeck/remove-extra-argument.fixed
@@ -0,0 +1,9 @@
+// run-rustfix
+// Check that the HELP suggestion is `l(vec![])` instead of `l($crate::vec::Vec::new())`
+fn l(_a: Vec<u8>) {}
+
+fn main() {
+    l(vec![])
+    //~^ ERROR this function takes 1 argument but 2 arguments were supplied
+    //~| HELP remove the extra argument
+}
diff --git a/src/test/ui/typeck/remove-extra-argument.rs b/src/test/ui/typeck/remove-extra-argument.rs
new file mode 100644
index 0000000000000..659cb8b267fd5
--- /dev/null
+++ b/src/test/ui/typeck/remove-extra-argument.rs
@@ -0,0 +1,9 @@
+// run-rustfix
+// Check that the HELP suggestion is `l(vec![])` instead of `l($crate::vec::Vec::new())`
+fn l(_a: Vec<u8>) {}
+
+fn main() {
+    l(vec![], vec![])
+    //~^ ERROR this function takes 1 argument but 2 arguments were supplied
+    //~| HELP remove the extra argument
+}
diff --git a/src/test/ui/typeck/remove-extra-argument.stderr b/src/test/ui/typeck/remove-extra-argument.stderr
new file mode 100644
index 0000000000000..815297765c18c
--- /dev/null
+++ b/src/test/ui/typeck/remove-extra-argument.stderr
@@ -0,0 +1,19 @@
+error[E0061]: this function takes 1 argument but 2 arguments were supplied
+  --> $DIR/remove-extra-argument.rs:6:5
+   |
+LL |     l(vec![], vec![])
+   |     ^         ------ argument unexpected
+   |
+note: function defined here
+  --> $DIR/remove-extra-argument.rs:3:4
+   |
+LL | fn l(_a: Vec<u8>) {}
+   |    ^ -----------
+help: remove the extra argument
+   |
+LL |     l(vec![])
+   |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0061`.