about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast/src/node_id.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs12
-rw-r--r--compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/back/archive.rs72
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs98
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs8
-rw-r--r--compiler/rustc_data_structures/src/fx.rs15
-rw-r--r--compiler/rustc_error_messages/locales/en-US/metadata.ftl3
-rw-r--r--compiler/rustc_error_messages/locales/en-US/passes.ftl3
-rw-r--r--compiler/rustc_errors/src/emitter.rs4
-rw-r--r--compiler/rustc_errors/src/lib.rs5
-rw-r--r--compiler/rustc_expand/src/base.rs39
-rw-r--r--compiler/rustc_feature/src/active.rs4
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs6
-rw-r--r--compiler/rustc_hir/src/hir_id.rs9
-rw-r--r--compiler/rustc_interface/src/tests.rs1
-rw-r--r--compiler/rustc_lint/src/levels.rs6
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs10
-rw-r--r--compiler/rustc_metadata/src/errors.rs6
-rw-r--r--compiler/rustc_metadata/src/lib.rs1
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs81
-rw-r--r--compiler/rustc_middle/src/ty/context.rs2
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs17
-rw-r--r--compiler/rustc_passes/src/check_attr.rs14
-rw-r--r--compiler/rustc_passes/src/errors.rs9
-rw-r--r--compiler/rustc_privacy/src/lib.rs1
-rw-r--r--compiler/rustc_session/src/cstore.rs2
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--compiler/rustc_span/src/def_id.rs9
-rw-r--r--compiler/rustc_span/src/hygiene.rs28
-rw-r--r--compiler/rustc_span/src/lib.rs7
-rw-r--r--compiler/rustc_span/src/symbol.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs4
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs5
-rw-r--r--library/core/src/ffi/c_str.rs19
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/slice/memchr.rs29
-rw-r--r--src/librustdoc/lint.rs9
-rw-r--r--src/librustdoc/passes/check_doc_test_visibility.rs2
-rw-r--r--src/librustdoc/passes/html_tags.rs85
-rw-r--r--src/test/debuginfo/collapse-debuginfo-no-attr-flag.rs61
-rw-r--r--src/test/debuginfo/collapse-debuginfo-no-attr.rs60
-rw-r--r--src/test/debuginfo/collapse-debuginfo-with-attr-flag.rs63
-rw-r--r--src/test/debuginfo/collapse-debuginfo-with-attr.rs59
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs-2/Makefile22
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs-2/main.rs5
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs-2/native_dep.rs4
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs-2/rust_dep.rs11
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs/Makefile34
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs/main.rs4
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs/native_dep_1.c1
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs/native_dep_2.c1
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs/native_dep_3.c1
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_local.rs13
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_up.rs13
-rw-r--r--src/test/rustdoc-ui/check-fail.rs1
-rw-r--r--src/test/rustdoc-ui/check-fail.stderr12
-rw-r--r--src/test/rustdoc-ui/check.rs4
-rw-r--r--src/test/rustdoc-ui/check.stderr18
-rw-r--r--src/test/rustdoc-ui/doc-without-codeblock.rs3
-rw-r--r--src/test/rustdoc-ui/doc-without-codeblock.stderr12
-rw-r--r--src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.rs10
-rw-r--r--src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.stderr29
-rw-r--r--src/test/rustdoc-ui/invalid-html-tags.rs7
-rw-r--r--src/test/rustdoc-ui/invalid-html-tags.stderr8
-rw-r--r--src/test/rustdoc-ui/lint-group.rs2
-rw-r--r--src/test/rustdoc-ui/lint-group.stderr12
-rw-r--r--src/test/rustdoc-ui/lint-missing-doc-code-example.rs1
-rw-r--r--src/test/rustdoc-ui/lint-missing-doc-code-example.stderr12
-rw-r--r--src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.rs42
-rw-r--r--src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.stderr48
-rw-r--r--src/test/rustdoc-ui/suggestions/html-as-generics.fixed40
-rw-r--r--src/test/rustdoc-ui/suggestions/html-as-generics.rs40
-rw-r--r--src/test/rustdoc-ui/suggestions/html-as-generics.stderr90
-rw-r--r--src/test/rustdoc-ui/z-help.stdout1
-rw-r--r--src/test/ui/async-await/issue-101715.rs17
-rw-r--r--src/test/ui/async-await/issue-101715.stderr16
-rw-r--r--src/test/ui/async-await/issue-70594.stderr10
-rw-r--r--src/test/ui/async-await/issues/issue-62009-1.stderr10
-rw-r--r--src/test/ui/attributes/collapse-debuginfo-invalid.rs110
-rw-r--r--src/test/ui/attributes/collapse-debuginfo-invalid.stderr222
-rw-r--r--src/test/ui/feature-gates/feature-gate-collapse_debuginfo.rs7
-rw-r--r--src/test/ui/feature-gates/feature-gate-collapse_debuginfo.stderr12
-rw-r--r--src/test/ui/proc-macro/dollar-crate-issue-101211.rs29
-rw-r--r--src/test/ui/typeof/issue-100183.rs6
-rw-r--r--src/test/ui/typeof/issue-100183.stderr14
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs7
m---------src/tools/miri14
-rw-r--r--triagebot.toml1
91 files changed, 1663 insertions, 200 deletions
diff --git a/compiler/rustc_ast/src/node_id.rs b/compiler/rustc_ast/src/node_id.rs
index 7f928cb5761..7b5acc3f485 100644
--- a/compiler/rustc_ast/src/node_id.rs
+++ b/compiler/rustc_ast/src/node_id.rs
@@ -13,7 +13,7 @@ rustc_index::newtype_index! {
     }
 }
 
-rustc_data_structures::define_id_collections!(NodeMap, NodeSet, NodeId);
+rustc_data_structures::define_id_collections!(NodeMap, NodeSet, NodeMapEntry, NodeId);
 
 /// The [`NodeId`] used to represent the root of the crate.
 pub const CRATE_NODE_ID: NodeId = NodeId::from_u32(0);
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index f929549d704..cd03e3fb457 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -146,13 +146,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         |this| this.with_new_scopes(|this| this.lower_block_expr(block)),
                     ),
                 ExprKind::Await(ref expr) => {
-                    let span = if expr.span.hi() < e.span.hi() {
-                        expr.span.shrink_to_hi().with_hi(e.span.hi())
+                    let dot_await_span = if expr.span.hi() < e.span.hi() {
+                        let span_with_whitespace = self
+                            .tcx
+                            .sess
+                            .source_map()
+                            .span_extend_while(expr.span, char::is_whitespace)
+                            .unwrap_or(expr.span);
+                        span_with_whitespace.shrink_to_hi().with_hi(e.span.hi())
                     } else {
                         // this is a recovered `await expr`
                         e.span
                     };
-                    self.lower_expr_await(span, expr)
+                    self.lower_expr_await(dot_await_span, expr)
                 }
                 ExprKind::Closure(
                     ref binder,
diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs
index 3ad0c420eaf..463de6a91c7 100644
--- a/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs
+++ b/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs
@@ -68,9 +68,9 @@ impl DebugContext {
     ) -> (Lrc<SourceFile>, u64, u64) {
         // Based on https://github.com/rust-lang/rust/blob/e369d87b015a84653343032833d65d0545fd3f26/src/librustc_codegen_ssa/mir/mod.rs#L116-L131
         // In order to have a good line stepping behavior in debugger, we overwrite debug
-        // locations of macro expansions with that of the outermost expansion site
-        // (unless the crate is being compiled with `-Z debug-macros`).
-        let span = if !span.from_expansion() || tcx.sess.opts.unstable_opts.debug_macros {
+        // locations of macro expansions with that of the outermost expansion site (when the macro is
+        // annotated with `#[collapse_debuginfo]` or when `-Zdebug-macros` is provided).
+        let span = if tcx.should_collapse_debuginfo(span) {
             span
         } else {
             // Walk up the macro expansion chain until we reach a non-expanded span.
diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs
index 0d2aa483d3d..bad58d0a8a0 100644
--- a/compiler/rustc_codegen_ssa/src/back/archive.rs
+++ b/compiler/rustc_codegen_ssa/src/back/archive.rs
@@ -1,44 +1,16 @@
+use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::memmap::Mmap;
 use rustc_session::cstore::DllImport;
 use rustc_session::Session;
+use rustc_span::symbol::Symbol;
 
+use object::read::archive::ArchiveFile;
+
+use std::fmt::Display;
+use std::fs::File;
 use std::io;
 use std::path::{Path, PathBuf};
 
-pub(super) fn find_library(
-    name: &str,
-    verbatim: bool,
-    search_paths: &[PathBuf],
-    sess: &Session,
-) -> PathBuf {
-    // On Windows, static libraries sometimes show up as libfoo.a and other
-    // times show up as foo.lib
-    let oslibname = if verbatim {
-        name.to_string()
-    } else {
-        format!("{}{}{}", sess.target.staticlib_prefix, name, sess.target.staticlib_suffix)
-    };
-    let unixlibname = format!("lib{}.a", name);
-
-    for path in search_paths {
-        debug!("looking for {} inside {:?}", name, path);
-        let test = path.join(&oslibname);
-        if test.exists() {
-            return test;
-        }
-        if oslibname != unixlibname {
-            let test = path.join(&unixlibname);
-            if test.exists() {
-                return test;
-            }
-        }
-    }
-    sess.fatal(&format!(
-        "could not find native static library `{}`, \
-                         perhaps an -L flag is missing?",
-        name
-    ));
-}
-
 pub trait ArchiveBuilderBuilder {
     fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder<'a> + 'a>;
 
@@ -54,6 +26,36 @@ pub trait ArchiveBuilderBuilder {
         dll_imports: &[DllImport],
         tmpdir: &Path,
     ) -> PathBuf;
+
+    fn extract_bundled_libs(
+        &self,
+        rlib: &Path,
+        outdir: &Path,
+        bundled_lib_file_names: &FxHashSet<Symbol>,
+    ) -> Result<(), String> {
+        let message = |msg: &str, e: &dyn Display| format!("{} '{}': {}", msg, &rlib.display(), e);
+        let archive_map = unsafe {
+            Mmap::map(File::open(rlib).map_err(|e| message("failed to open file", &e))?)
+                .map_err(|e| message("failed to mmap file", &e))?
+        };
+        let archive = ArchiveFile::parse(&*archive_map)
+            .map_err(|e| message("failed to parse archive", &e))?;
+
+        for entry in archive.members() {
+            let entry = entry.map_err(|e| message("failed to read entry", &e))?;
+            let data = entry
+                .data(&*archive_map)
+                .map_err(|e| message("failed to get data from archive member", &e))?;
+            let name = std::str::from_utf8(entry.name())
+                .map_err(|e| message("failed to convert name", &e))?;
+            if !bundled_lib_file_names.contains(&Symbol::intern(name)) {
+                continue; // We need to extract only native libraries.
+            }
+            std::fs::write(&outdir.join(&name), data)
+                .map_err(|e| message("failed to write file", &e))?;
+        }
+        Ok(())
+    }
 }
 
 pub trait ArchiveBuilder<'a> {
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index d7c7037ce1a..c5e18c7fae8 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -1,11 +1,13 @@
 use rustc_arena::TypedArena;
 use rustc_ast::CRATE_NODE_ID;
+use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::memmap::Mmap;
 use rustc_data_structures::temp_dir::MaybeTempDir;
 use rustc_errors::{ErrorGuaranteed, Handler};
 use rustc_fs_util::fix_windows_verbatim_for_gcc;
 use rustc_hir::def_id::CrateNum;
+use rustc_metadata::find_native_static_library;
 use rustc_metadata::fs::{emit_metadata, METADATA_FILENAME};
 use rustc_middle::middle::dependency_format::Linkage;
 use rustc_middle::middle::exported_symbols::SymbolExportKind;
@@ -24,7 +26,7 @@ use rustc_target::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault};
 use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor, SplitDebuginfo};
 use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, SanitizerSet, Target};
 
-use super::archive::{find_library, ArchiveBuilder, ArchiveBuilderBuilder};
+use super::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
 use super::command::Command;
 use super::linker::{self, Linker};
 use super::metadata::{create_rmeta_file, MetadataPosition};
@@ -307,6 +309,9 @@ fn link_rlib<'a>(
         }
     }
 
+    // Used if packed_bundled_libs flag enabled.
+    let mut packed_bundled_libs = Vec::new();
+
     // Note that in this loop we are ignoring the value of `lib.cfg`. That is,
     // we may not be configured to actually include a static library if we're
     // adding it here. That's because later when we consume this rlib we'll
@@ -326,6 +331,8 @@ fn link_rlib<'a>(
     for lib in codegen_results.crate_info.used_libraries.iter() {
         match lib.kind {
             NativeLibKind::Static { bundle: None | Some(true), whole_archive: Some(true) }
+                if flavor == RlibFlavor::Normal && sess.opts.unstable_opts.packed_bundled_libs => {}
+            NativeLibKind::Static { bundle: None | Some(true), whole_archive: Some(true) }
                 if flavor == RlibFlavor::Normal =>
             {
                 // Don't allow mixing +bundle with +whole_archive since an rlib may contain
@@ -348,7 +355,16 @@ fn link_rlib<'a>(
         }
         if let Some(name) = lib.name {
             let location =
-                find_library(name.as_str(), lib.verbatim.unwrap_or(false), &lib_search_paths, sess);
+                find_native_static_library(name.as_str(), lib.verbatim, &lib_search_paths, sess);
+            if sess.opts.unstable_opts.packed_bundled_libs && flavor == RlibFlavor::Normal {
+                packed_bundled_libs.push(find_native_static_library(
+                    lib.filename.unwrap().as_str(),
+                    Some(true),
+                    &lib_search_paths,
+                    sess,
+                ));
+                continue;
+            }
             ab.add_archive(&location, Box::new(|_| false)).unwrap_or_else(|e| {
                 sess.fatal(&format!(
                     "failed to add native library {}: {}",
@@ -403,6 +419,12 @@ fn link_rlib<'a>(
         ab.add_file(&trailing_metadata);
     }
 
+    // Add all bundled static native library dependencies.
+    // Archives added to the end of .rlib archive, see comment above for the reason.
+    for lib in packed_bundled_libs {
+        ab.add_file(&lib)
+    }
+
     return Ok(ab);
 }
 
@@ -2341,7 +2363,15 @@ fn add_upstream_rust_crates<'a>(
         let src = &codegen_results.crate_info.used_crate_source[&cnum];
         match data[cnum.as_usize() - 1] {
             _ if codegen_results.crate_info.profiler_runtime == Some(cnum) => {
-                add_static_crate(cmd, sess, archive_builder_builder, codegen_results, tmpdir, cnum);
+                add_static_crate(
+                    cmd,
+                    sess,
+                    archive_builder_builder,
+                    codegen_results,
+                    tmpdir,
+                    cnum,
+                    &Default::default(),
+                );
             }
             // compiler-builtins are always placed last to ensure that they're
             // linked correctly.
@@ -2351,7 +2381,23 @@ fn add_upstream_rust_crates<'a>(
             }
             Linkage::NotLinked | Linkage::IncludedFromDylib => {}
             Linkage::Static => {
-                add_static_crate(cmd, sess, archive_builder_builder, codegen_results, tmpdir, cnum);
+                let bundled_libs = if sess.opts.unstable_opts.packed_bundled_libs {
+                    codegen_results.crate_info.native_libraries[&cnum]
+                        .iter()
+                        .filter_map(|lib| lib.filename)
+                        .collect::<FxHashSet<_>>()
+                } else {
+                    Default::default()
+                };
+                add_static_crate(
+                    cmd,
+                    sess,
+                    archive_builder_builder,
+                    codegen_results,
+                    tmpdir,
+                    cnum,
+                    &bundled_libs,
+                );
 
                 // Link static native libs with "-bundle" modifier only if the crate they originate from
                 // is being linked statically to the current crate.  If it's linked dynamically
@@ -2362,6 +2408,14 @@ fn add_upstream_rust_crates<'a>(
                 // external build system already has the native dependencies defined, and it
                 // will provide them to the linker itself.
                 if sess.opts.unstable_opts.link_native_libraries {
+                    if sess.opts.unstable_opts.packed_bundled_libs {
+                        // If rlib contains native libs as archives, unpack them to tmpdir.
+                        let rlib = &src.rlib.as_ref().unwrap().0;
+                        archive_builder_builder
+                            .extract_bundled_libs(rlib, tmpdir, &bundled_libs)
+                            .unwrap_or_else(|e| sess.fatal(e));
+                    }
+
                     let mut last = (None, NativeLibKind::Unspecified, None);
                     for lib in &codegen_results.crate_info.native_libraries[&cnum] {
                         let Some(name) = lib.name else {
@@ -2411,10 +2465,17 @@ fn add_upstream_rust_crates<'a>(
                             | NativeLibKind::Framework { .. }
                             | NativeLibKind::Unspecified
                             | NativeLibKind::RawDylib => {}
-                            NativeLibKind::Static {
-                                bundle: Some(true) | None,
-                                whole_archive: _,
-                            } => {}
+                            NativeLibKind::Static { bundle: Some(true) | None, whole_archive } => {
+                                if sess.opts.unstable_opts.packed_bundled_libs {
+                                    // If rlib contains native libs as archives, they are unpacked to tmpdir.
+                                    let path = tmpdir.join(lib.filename.unwrap().as_str());
+                                    if whole_archive == Some(true) {
+                                        cmd.link_whole_rlib(&path);
+                                    } else {
+                                        cmd.link_rlib(&path);
+                                    }
+                                }
+                            }
                         }
                     }
                 }
@@ -2429,7 +2490,15 @@ fn add_upstream_rust_crates<'a>(
     // was already "included" in a dylib (e.g., `libstd` when `-C prefer-dynamic`
     // is used)
     if let Some(cnum) = compiler_builtins {
-        add_static_crate(cmd, sess, archive_builder_builder, codegen_results, tmpdir, cnum);
+        add_static_crate(
+            cmd,
+            sess,
+            archive_builder_builder,
+            codegen_results,
+            tmpdir,
+            cnum,
+            &Default::default(),
+        );
     }
 
     // Converts a library file-stem into a cc -l argument
@@ -2462,6 +2531,7 @@ fn add_upstream_rust_crates<'a>(
         codegen_results: &CodegenResults,
         tmpdir: &Path,
         cnum: CrateNum,
+        bundled_lib_file_names: &FxHashSet<Symbol>,
     ) {
         let src = &codegen_results.crate_info.used_crate_source[&cnum];
         let cratepath = &src.rlib.as_ref().unwrap().0;
@@ -2490,6 +2560,7 @@ fn add_upstream_rust_crates<'a>(
         let dst = tmpdir.join(cratepath.file_name().unwrap());
         let name = cratepath.file_name().unwrap().to_str().unwrap();
         let name = &name[3..name.len() - 5]; // chop off lib/.rlib
+        let bundled_lib_file_names = bundled_lib_file_names.clone();
 
         sess.prof.generic_activity_with_arg("link_altering_rlib", name).run(|| {
             let canonical_name = name.replace('-', "_");
@@ -2523,6 +2594,15 @@ fn add_upstream_rust_crates<'a>(
                     let skip_because_lto =
                         upstream_rust_objects_already_included && is_rust_object && is_builtins;
 
+                    // We skip native libraries because:
+                    // 1. This native libraries won't be used from the generated rlib,
+                    //    so we can throw them away to avoid the copying work.
+                    // 2. We can't allow it to be a single remaining entry in archive
+                    //    as some linkers may complain on that.
+                    if bundled_lib_file_names.contains(&Symbol::intern(f)) {
+                        return true;
+                    }
+
                     if skip_because_cfg_say_so || skip_because_lto {
                         return true;
                     }
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 949a356fce1..e505543b27c 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -1,4 +1,3 @@
-use super::archive;
 use super::command::Command;
 use super::symbol_export;
 use rustc_span::symbol::sym;
@@ -11,6 +10,7 @@ use std::path::{Path, PathBuf};
 use std::{env, mem, str};
 
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
+use rustc_metadata::find_native_static_library;
 use rustc_middle::middle::dependency_format::Linkage;
 use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo, SymbolExportKind};
 use rustc_middle::ty::TyCtxt;
@@ -514,7 +514,7 @@ impl<'a> Linker for GccLinker<'a> {
             // -force_load is the macOS equivalent of --whole-archive, but it
             // involves passing the full path to the library to link.
             self.linker_arg("-force_load");
-            let lib = archive::find_library(lib, verbatim, search_path, &self.sess);
+            let lib = find_native_static_library(lib, Some(verbatim), search_path, &self.sess);
             self.linker_arg(&lib);
         }
     }
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 52da7abcac5..4ea75dba471 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -112,6 +112,7 @@ bitflags::bitflags! {
 pub struct NativeLib {
     pub kind: NativeLibKind,
     pub name: Option<Symbol>,
+    pub filename: Option<Symbol>,
     pub cfg: Option<ast::MetaItem>,
     pub verbatim: Option<bool>,
     pub dll_imports: Vec<cstore::DllImport>,
@@ -121,6 +122,7 @@ impl From<&cstore::NativeLib> for NativeLib {
     fn from(lib: &cstore::NativeLib) -> Self {
         NativeLib {
             kind: lib.kind,
+            filename: lib.filename,
             name: lib.name,
             cfg: lib.cfg.clone(),
             verbatim: lib.verbatim,
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index 8c3186efc63..157c1c82311 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -3,7 +3,7 @@ use rustc_index::vec::IndexVec;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir;
 use rustc_middle::ty;
-use rustc_middle::ty::layout::LayoutOf;
+use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
 use rustc_session::config::DebugInfo;
 use rustc_span::symbol::{kw, Symbol};
 use rustc_span::{BytePos, Span};
@@ -93,15 +93,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     }
 
     /// In order to have a good line stepping behavior in debugger, we overwrite debug
-    /// locations of macro expansions with that of the outermost expansion site
-    /// (unless the crate is being compiled with `-Z debug-macros`).
+    /// locations of macro expansions with that of the outermost expansion site (when the macro is
+    /// annotated with `#[collapse_debuginfo]` or when `-Zdebug-macros` is provided).
     fn adjust_span_for_debugging(&self, mut span: Span) -> Span {
         // Bail out if debug info emission is not enabled.
         if self.debug_context.is_none() {
             return span;
         }
 
-        if span.from_expansion() && !self.cx.sess().opts.unstable_opts.debug_macros {
+        if self.cx.tcx().should_collapse_debuginfo(span) {
             // Walk up the macro expansion chain until we reach a non-expanded span.
             // We also stop at the function body level because no line stepping can occur
             // at the level above that.
diff --git a/compiler/rustc_data_structures/src/fx.rs b/compiler/rustc_data_structures/src/fx.rs
index bbeb193dba3..0d0c51b6819 100644
--- a/compiler/rustc_data_structures/src/fx.rs
+++ b/compiler/rustc_data_structures/src/fx.rs
@@ -2,13 +2,26 @@ use std::hash::BuildHasherDefault;
 
 pub use rustc_hash::{FxHashMap, FxHashSet, FxHasher};
 
+pub type StdEntry<'a, K, V> = std::collections::hash_map::Entry<'a, K, V>;
+
 pub type FxIndexMap<K, V> = indexmap::IndexMap<K, V, BuildHasherDefault<FxHasher>>;
 pub type FxIndexSet<V> = indexmap::IndexSet<V, BuildHasherDefault<FxHasher>>;
+pub type IndexEntry<'a, K, V> = indexmap::map::Entry<'a, K, V>;
 
 #[macro_export]
 macro_rules! define_id_collections {
-    ($map_name:ident, $set_name:ident, $key:ty) => {
+    ($map_name:ident, $set_name:ident, $entry_name:ident, $key:ty) => {
         pub type $map_name<T> = $crate::fx::FxHashMap<$key, T>;
         pub type $set_name = $crate::fx::FxHashSet<$key>;
+        pub type $entry_name<'a, T> = $crate::fx::StdEntry<'a, $key, T>;
+    };
+}
+
+#[macro_export]
+macro_rules! define_stable_id_collections {
+    ($map_name:ident, $set_name:ident, $entry_name:ident, $key:ty) => {
+        pub type $map_name<T> = $crate::fx::FxIndexMap<$key, T>;
+        pub type $set_name = $crate::fx::FxIndexSet<$key>;
+        pub type $entry_name<'a, T> = $crate::fx::IndexEntry<'a, $key, T>;
     };
 }
diff --git a/compiler/rustc_error_messages/locales/en-US/metadata.ftl b/compiler/rustc_error_messages/locales/en-US/metadata.ftl
index 00067a1bf6a..d27100c56af 100644
--- a/compiler/rustc_error_messages/locales/en-US/metadata.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/metadata.ftl
@@ -162,6 +162,9 @@ metadata_no_transitive_needs_dep =
 metadata_failed_write_error =
     failed to write {$filename}: {$err}
 
+metadata_missing_native_library =
+    could not find native static library `{$libname}`, perhaps an -L flag is missing?
+
 metadata_failed_create_tempdir =
     couldn't create a temp dir: {$err}
 
diff --git a/compiler/rustc_error_messages/locales/en-US/passes.ftl b/compiler/rustc_error_messages/locales/en-US/passes.ftl
index 7374f6d3f27..556a6452f1a 100644
--- a/compiler/rustc_error_messages/locales/en-US/passes.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/passes.ftl
@@ -265,3 +265,6 @@ passes_rustc_lint_opt_deny_field_access = `#[rustc_lint_opt_deny_field_access]`
 
 passes_link_ordinal = attribute should be applied to a foreign function or static
     .label = not a foreign function or static
+
+passes_collapse_debuginfo = `collapse_debuginfo` attribute should be applied to macro definitions
+    .label = not a macro definition
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index e79ce11a6fc..1d260f7cafc 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -22,7 +22,7 @@ use crate::{
 
 use rustc_lint_defs::pluralize;
 
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_data_structures::sync::Lrc;
 use rustc_error_messages::FluentArgs;
 use rustc_span::hygiene::{ExpnKind, MacroKind};
@@ -1487,7 +1487,7 @@ impl EmitterWriter {
                 );
 
                 // Contains the vertical lines' positions for active multiline annotations
-                let mut multilines = FxHashMap::default();
+                let mut multilines = FxIndexMap::default();
 
                 // Get the left-side margin to remove it
                 let mut whitespace_margin = usize::MAX;
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 3e02d2ebb7e..fb7ae6f99cf 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -12,7 +12,6 @@
 #![feature(result_option_inspect)]
 #![feature(rustc_attrs)]
 #![allow(incomplete_features)]
-#![allow(rustc::potential_query_instability)]
 
 #[macro_use]
 extern crate rustc_macros;
@@ -27,7 +26,7 @@ use Level::*;
 
 use emitter::{is_case_difference, Emitter, EmitterWriter};
 use registry::Registry;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
+use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_data_structures::stable_hasher::StableHasher;
 use rustc_data_structures::sync::{self, Lock, Lrc};
 use rustc_data_structures::AtomicRef;
@@ -413,7 +412,7 @@ struct HandlerInner {
     taught_diagnostics: FxHashSet<DiagnosticId>,
 
     /// Used to suggest rustc --explain <error code>
-    emitted_diagnostic_codes: FxHashSet<DiagnosticId>,
+    emitted_diagnostic_codes: FxIndexSet<DiagnosticId>,
 
     /// This set contains a hash of every diagnostic that has been emitted by
     /// this handler. These hashes is used to avoid emitting the same error
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 2bb522caa2d..e1da3ecdec7 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -693,10 +693,6 @@ pub struct SyntaxExtension {
     pub span: Span,
     /// List of unstable features that are treated as stable inside this macro.
     pub allow_internal_unstable: Option<Lrc<[Symbol]>>,
-    /// Suppresses the `unsafe_code` lint for code produced by this macro.
-    pub allow_internal_unsafe: bool,
-    /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro.
-    pub local_inner_macros: bool,
     /// The macro's stability info.
     pub stability: Option<Stability>,
     /// The macro's deprecation info.
@@ -708,6 +704,13 @@ pub struct SyntaxExtension {
     /// Built-in macros have a couple of special properties like availability
     /// in `#[no_implicit_prelude]` modules, so we have to keep this flag.
     pub builtin_name: Option<Symbol>,
+    /// Suppresses the `unsafe_code` lint for code produced by this macro.
+    pub allow_internal_unsafe: bool,
+    /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro.
+    pub local_inner_macros: bool,
+    /// Should debuginfo for the macro be collapsed to the outermost expansion site (in other
+    /// words, was the macro definition annotated with `#[collapse_debuginfo]`)?
+    pub collapse_debuginfo: bool,
 }
 
 impl SyntaxExtension {
@@ -729,14 +732,15 @@ impl SyntaxExtension {
         SyntaxExtension {
             span: DUMMY_SP,
             allow_internal_unstable: None,
-            allow_internal_unsafe: false,
-            local_inner_macros: false,
             stability: None,
             deprecation: None,
             helper_attrs: Vec::new(),
             edition,
             builtin_name: None,
             kind,
+            allow_internal_unsafe: false,
+            local_inner_macros: false,
+            collapse_debuginfo: false,
         }
     }
 
@@ -754,12 +758,13 @@ impl SyntaxExtension {
         let allow_internal_unstable =
             attr::allow_internal_unstable(sess, &attrs).collect::<Vec<Symbol>>();
 
-        let mut local_inner_macros = false;
-        if let Some(macro_export) = sess.find_by_name(attrs, sym::macro_export) {
-            if let Some(l) = macro_export.meta_item_list() {
-                local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros);
-            }
-        }
+        let allow_internal_unsafe = sess.contains_name(attrs, sym::allow_internal_unsafe);
+        let local_inner_macros = sess
+            .find_by_name(attrs, sym::macro_export)
+            .and_then(|macro_export| macro_export.meta_item_list())
+            .map_or(false, |l| attr::list_contains_name(&l, sym::local_inner_macros));
+        let collapse_debuginfo = sess.contains_name(attrs, sym::collapse_debuginfo);
+        tracing::debug!(?local_inner_macros, ?collapse_debuginfo, ?allow_internal_unsafe);
 
         let (builtin_name, helper_attrs) = sess
             .find_by_name(attrs, sym::rustc_builtin_macro)
@@ -801,13 +806,14 @@ impl SyntaxExtension {
             span,
             allow_internal_unstable: (!allow_internal_unstable.is_empty())
                 .then(|| allow_internal_unstable.into()),
-            allow_internal_unsafe: sess.contains_name(attrs, sym::allow_internal_unsafe),
-            local_inner_macros,
             stability: stability.map(|(s, _)| s),
             deprecation: attr::find_deprecation(&sess, attrs).map(|(d, _)| d),
             helper_attrs,
             edition,
             builtin_name,
+            allow_internal_unsafe,
+            local_inner_macros,
+            collapse_debuginfo,
         }
     }
 
@@ -852,11 +858,12 @@ impl SyntaxExtension {
             call_site,
             self.span,
             self.allow_internal_unstable.clone(),
-            self.allow_internal_unsafe,
-            self.local_inner_macros,
             self.edition,
             macro_def_id,
             parent_module,
+            self.allow_internal_unsafe,
+            self.local_inner_macros,
+            self.collapse_debuginfo,
         )
     }
 }
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 5377ebde168..9232b774e26 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -221,6 +221,8 @@ declare_features! (
     (active, rustc_private, "1.0.0", Some(27812), None),
     /// Allows using internal rustdoc features like `doc(primitive)` or `doc(keyword)`.
     (active, rustdoc_internals, "1.58.0", Some(90418), None),
+    /// Allows using the `rustdoc::missing_doc_code_examples` lint
+    (active, rustdoc_missing_doc_code_examples, "1.31.0", Some(101730), None),
     /// Allows using `#[start]` on a function indicating that it is the program entrypoint.
     (active, start, "1.0.0", Some(29633), None),
     /// Allows using `#[structural_match]` which indicates that a type is structurally matchable.
@@ -336,6 +338,8 @@ declare_features! (
     (active, closure_track_caller, "1.57.0", Some(87417), None),
     /// Allows to use the `#[cmse_nonsecure_entry]` attribute.
     (active, cmse_nonsecure_entry, "1.48.0", Some(75835), None),
+    /// Allows use of the `#[collapse_debuginfo]` attribute.
+    (active, collapse_debuginfo, "CURRENT_RUSTC_VERSION", Some(100758), None),
     /// Allows `async {}` expressions in const contexts.
     (active, const_async_blocks, "1.53.0", Some(85368), None),
     // Allows limiting the evaluation steps of const expressions
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 8d88a90e395..b50c972e6f6 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -478,6 +478,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         experimental!(deprecated_safe),
     ),
 
+    // `#[collapse_debuginfo]`
+    gated!(
+        collapse_debuginfo, Normal, template!(Word), WarnFollowing,
+        experimental!(collapse_debuginfo)
+    ),
+
     // ==========================================================================
     // Internal attributes: Stability, deprecation, and unsafe:
     // ==========================================================================
diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs
index e586d5cd5d9..84b0740c7b3 100644
--- a/compiler/rustc_hir/src/hir_id.rs
+++ b/compiler/rustc_hir/src/hir_id.rs
@@ -67,8 +67,13 @@ impl PartialOrd for HirId {
     }
 }
 
-rustc_data_structures::define_id_collections!(HirIdMap, HirIdSet, HirId);
-rustc_data_structures::define_id_collections!(ItemLocalMap, ItemLocalSet, ItemLocalId);
+rustc_data_structures::define_stable_id_collections!(HirIdMap, HirIdSet, HirIdMapEntry, HirId);
+rustc_data_structures::define_id_collections!(
+    ItemLocalMap,
+    ItemLocalSet,
+    ItemLocalMapEntry,
+    ItemLocalId
+);
 
 rustc_index::newtype_index! {
     /// An `ItemLocalId` uniquely identifies something within a given "item-like";
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 5df5ab3ddc0..c7615a5775e 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -765,6 +765,7 @@ fn test_unstable_options_tracking_hash() {
     tracked!(no_profiler_runtime, true);
     tracked!(oom, OomStrategy::Panic);
     tracked!(osx_rpath_install_name, true);
+    tracked!(packed_bundled_libs, true);
     tracked!(panic_abort_tests, true);
     tracked!(panic_in_drop, PanicStrategy::Abort);
     tracked!(pick_stable_methods_before_any_unstable, false);
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index f1d8ef2e47d..1e16ac51e9e 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -440,8 +440,10 @@ impl<'s> LintLevelsBuilder<'s> {
                                     sp,
                                     reason,
                                 );
-                                for id in ids {
-                                    self.insert_spec(*id, (level, src));
+                                for &id in ids {
+                                    if self.check_gated_lint(id, attr.span) {
+                                        self.insert_spec(id, (level, src));
+                                    }
                                 }
                                 if let Level::Expect(expect_id) = level {
                                     self.lint_expectations.push((
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 9c6530c8a08..11b2d057a07 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -658,18 +658,21 @@ macro_rules! declare_lint {
 macro_rules! declare_tool_lint {
     (
         $(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level: ident, $desc: expr
+        $(, @feature_gate = $gate:expr;)?
     ) => (
-        $crate::declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, false}
+        $crate::declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, false $(, @feature_gate = $gate;)?}
     );
     (
         $(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level:ident, $desc:expr,
         report_in_external_macro: $rep:expr
+        $(, @feature_gate = $gate:expr;)?
     ) => (
-         $crate::declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, $rep}
+         $crate::declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, $rep $(, @feature_gate = $gate;)?}
     );
     (
         $(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level:ident, $desc:expr,
         $external:expr
+        $(, @feature_gate = $gate:expr;)?
     ) => (
         $(#[$attr])*
         $vis static $NAME: &$crate::Lint = &$crate::Lint {
@@ -680,8 +683,9 @@ macro_rules! declare_tool_lint {
             report_in_external_macro: $external,
             future_incompatible: None,
             is_plugin: true,
-            feature_gate: None,
+            $(feature_gate: Some($gate),)?
             crate_level_only: false,
+            ..$crate::Lint::default_fields_for_macro()
         };
     );
 }
diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs
index 1406ee914af..7d63fad3240 100644
--- a/compiler/rustc_metadata/src/errors.rs
+++ b/compiler/rustc_metadata/src/errors.rs
@@ -370,6 +370,12 @@ pub struct FailedWriteError {
 }
 
 #[derive(SessionDiagnostic)]
+#[diag(metadata::missing_native_library)]
+pub struct MissingNativeLibrary<'a> {
+    pub libname: &'a str,
+}
+
+#[derive(SessionDiagnostic)]
 #[diag(metadata::failed_create_tempdir)]
 pub struct FailedCreateTempdir {
     pub err: Error,
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index 8e0291fc3ad..57c5ec2f28c 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -44,4 +44,5 @@ pub mod fs;
 pub mod locator;
 
 pub use fs::{emit_metadata, METADATA_FILENAME};
+pub use native_libs::find_native_static_library;
 pub use rmeta::{encode_metadata, EncodedMetadata, METADATA_HEADER};
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index 3acabc4e69c..cc33ad07db6 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -4,8 +4,10 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_middle::ty::{List, ParamEnv, ParamEnvAnd, Ty, TyCtxt};
+use rustc_session::config::CrateType;
 use rustc_session::cstore::{DllCallingConvention, DllImport, NativeLib, PeImportNameType};
 use rustc_session::parse::feature_err;
+use rustc_session::search_paths::PathKind;
 use rustc_session::utils::NativeLibKind;
 use rustc_session::Session;
 use rustc_span::symbol::{sym, Symbol};
@@ -16,13 +18,66 @@ use crate::errors::{
     FrameworkOnlyWindows, ImportNameTypeForm, ImportNameTypeRaw, ImportNameTypeX86,
     IncompatibleWasmLink, InvalidLinkModifier, LibFrameworkApple, LinkCfgForm,
     LinkCfgSinglePredicate, LinkFrameworkApple, LinkKindForm, LinkModifiersForm, LinkNameForm,
-    LinkOrdinalRawDylib, LinkRequiresName, MultipleCfgs, MultipleImportNameType,
-    MultipleKindsInLink, MultipleLinkModifiers, MultipleModifiers, MultipleNamesInLink,
-    MultipleRenamings, MultipleWasmImport, NoLinkModOverride, RawDylibNoNul, RenamingNoLink,
-    UnexpectedLinkArg, UnknownImportNameType, UnknownLinkKind, UnknownLinkModifier, UnsupportedAbi,
-    UnsupportedAbiI686, WasmImportForm, WholeArchiveNeedsStatic,
+    LinkOrdinalRawDylib, LinkRequiresName, MissingNativeLibrary, MultipleCfgs,
+    MultipleImportNameType, MultipleKindsInLink, MultipleLinkModifiers, MultipleModifiers,
+    MultipleNamesInLink, MultipleRenamings, MultipleWasmImport, NoLinkModOverride, RawDylibNoNul,
+    RenamingNoLink, UnexpectedLinkArg, UnknownImportNameType, UnknownLinkKind, UnknownLinkModifier,
+    UnsupportedAbi, UnsupportedAbiI686, WasmImportForm, WholeArchiveNeedsStatic,
 };
 
+use std::path::PathBuf;
+
+pub fn find_native_static_library(
+    name: &str,
+    verbatim: Option<bool>,
+    search_paths: &[PathBuf],
+    sess: &Session,
+) -> PathBuf {
+    let verbatim = verbatim.unwrap_or(false);
+    // On Windows, static libraries sometimes show up as libfoo.a and other
+    // times show up as foo.lib
+    let oslibname = if verbatim {
+        name.to_string()
+    } else {
+        format!("{}{}{}", sess.target.staticlib_prefix, name, sess.target.staticlib_suffix)
+    };
+    let unixlibname = format!("lib{}.a", name);
+
+    for path in search_paths {
+        let test = path.join(&oslibname);
+        if test.exists() {
+            return test;
+        }
+        if oslibname != unixlibname {
+            let test = path.join(&unixlibname);
+            if test.exists() {
+                return test;
+            }
+        }
+    }
+    sess.emit_fatal(MissingNativeLibrary { libname: name });
+}
+
+fn find_bundled_library(
+    name: Option<Symbol>,
+    verbatim: Option<bool>,
+    kind: NativeLibKind,
+    sess: &Session,
+) -> Option<Symbol> {
+    if sess.opts.unstable_opts.packed_bundled_libs &&
+            sess.crate_types().iter().any(|ct| ct == &CrateType::Rlib || ct == &CrateType::Staticlib) &&
+            let NativeLibKind::Static { bundle: Some(true) | None, .. } = kind {
+        find_native_static_library(
+            name.unwrap().as_str(),
+            verbatim,
+            &sess.target_filesearch(PathKind::Native).search_path_dirs(),
+            sess,
+        ).file_name().and_then(|s| s.to_str()).map(Symbol::intern)
+    } else {
+        None
+    }
+}
+
 pub(crate) fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLib> {
     let mut collector = Collector { tcx, libs: Vec::new() };
     for id in tcx.hir().items() {
@@ -341,9 +396,14 @@ impl<'tcx> Collector<'tcx> {
                     Vec::new()
                 }
             };
+
+            let name = name.map(|(name, _)| name);
+            let kind = kind.unwrap_or(NativeLibKind::Unspecified);
+            let filename = find_bundled_library(name, verbatim, kind, sess);
             self.libs.push(NativeLib {
-                name: name.map(|(name, _)| name),
-                kind: kind.unwrap_or(NativeLibKind::Unspecified),
+                name,
+                filename,
+                kind,
                 cfg,
                 foreign_module: Some(it.def_id.to_def_id()),
                 wasm_import_module: wasm_import_module.map(|(name, _)| name),
@@ -423,8 +483,13 @@ impl<'tcx> Collector<'tcx> {
             if existing.is_empty() {
                 // Add if not found
                 let new_name: Option<&str> = passed_lib.new_name.as_deref();
+                let name = Some(Symbol::intern(new_name.unwrap_or(&passed_lib.name)));
+                let sess = self.tcx.sess;
+                let filename =
+                    find_bundled_library(name, passed_lib.verbatim, passed_lib.kind, sess);
                 self.libs.push(NativeLib {
-                    name: Some(Symbol::intern(new_name.unwrap_or(&passed_lib.name))),
+                    name,
+                    filename,
                     kind: passed_lib.kind,
                     cfg: None,
                     foreign_module: None,
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index afb2d5b2ba5..94eddef944a 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1590,7 +1590,7 @@ impl<'tcx> TyCtxt<'tcx> {
         })
     }
 
-    // Returns the `DefId` and the `BoundRegionKind` corresponding to the given region.
+    /// Returns the `DefId` and the `BoundRegionKind` corresponding to the given region.
     pub fn is_suitable_region(self, region: Region<'tcx>) -> Option<FreeRegionInfo> {
         let (suitable_region_binding_scope, bound_region) = match *region {
             ty::ReFree(ref free_region) => {
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index df72260597f..3ff62647105 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -2470,6 +2470,23 @@ impl<'tcx> TyCtxt<'tcx> {
         (ident, scope)
     }
 
+    /// Returns `true` if the debuginfo for `span` should be collapsed to the outermost expansion
+    /// site. Only applies when `Span` is the result of macro expansion.
+    ///
+    /// - If the `collapse_debuginfo` feature is enabled then debuginfo is not collapsed by default
+    ///   and only when a macro definition is annotated with `#[collapse_debuginfo]`.
+    /// - If `collapse_debuginfo` is not enabled, then debuginfo is collapsed by default.
+    ///
+    /// When `-Zdebug-macros` is provided then debuginfo will never be collapsed.
+    pub fn should_collapse_debuginfo(self, span: Span) -> bool {
+        !self.sess.opts.unstable_opts.debug_macros
+            && if self.features().collapse_debuginfo {
+                span.in_macro_expansion_with_collapse_debuginfo()
+            } else {
+                span.from_expansion()
+            }
+    }
+
     pub fn is_object_safe(self, key: DefId) -> bool {
         self.object_safety_violations(key).is_empty()
     }
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index bb684e784c5..ebe4d2e9dd0 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -131,6 +131,7 @@ impl CheckAttrVisitor<'_> {
                 | sym::rustc_if_this_changed
                 | sym::rustc_then_this_would_need => self.check_rustc_dirty_clean(&attr),
                 sym::cmse_nonsecure_entry => self.check_cmse_nonsecure_entry(attr, span, target),
+                sym::collapse_debuginfo => self.check_collapse_debuginfo(attr, span, target),
                 sym::const_trait => self.check_const_trait(attr, span, target),
                 sym::must_not_suspend => self.check_must_not_suspend(&attr, span, target),
                 sym::must_use => self.check_must_use(hir_id, &attr, span, target),
@@ -431,6 +432,19 @@ impl CheckAttrVisitor<'_> {
         }
     }
 
+    /// Checks if `#[collapse_debuginfo]` is applied to a macro.
+    fn check_collapse_debuginfo(&self, attr: &Attribute, span: Span, target: Target) -> bool {
+        match target {
+            Target::MacroDef => true,
+            _ => {
+                self.tcx
+                    .sess
+                    .emit_err(errors::CollapseDebuginfo { attr_span: attr.span, defn_span: span });
+                false
+            }
+        }
+    }
+
     /// Checks if a `#[track_caller]` is applied to a non-naked function. Returns `true` if valid.
     fn check_track_caller(
         &self,
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 901f56ad96d..96cc8ae988c 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -649,3 +649,12 @@ pub struct RustcLintOptDenyFieldAccess {
     #[label]
     pub span: Span,
 }
+
+#[derive(SessionDiagnostic)]
+#[diag(passes::collapse_debuginfo)]
+pub struct CollapseDebuginfo {
+    #[primary_span]
+    pub attr_span: Span,
+    #[label]
+    pub defn_span: Span,
+}
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index afd423dc5fa..b8e81bb5d20 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -5,7 +5,6 @@
 #![feature(rustc_private)]
 #![feature(try_blocks)]
 #![recursion_limit = "256"]
-#![allow(rustc::potential_query_instability)]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
 
diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs
index 11ef75bb2d4..7d4a1e212a4 100644
--- a/compiler/rustc_session/src/cstore.rs
+++ b/compiler/rustc_session/src/cstore.rs
@@ -68,6 +68,8 @@ pub enum LinkagePreference {
 pub struct NativeLib {
     pub kind: NativeLibKind,
     pub name: Option<Symbol>,
+    /// If packed_bundled_libs enabled, actual filename of library is stored.
+    pub filename: Option<Symbol>,
     pub cfg: Option<ast::MetaItem>,
     pub foreign_module: Option<DefId>,
     pub wasm_import_module: Option<Symbol>,
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index a25e3362a0c..d7f1bc0be84 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1441,6 +1441,8 @@ options! {
         "pass `-install_name @rpath/...` to the macOS linker (default: no)"),
     diagnostic_width: Option<usize> = (None, parse_opt_number, [UNTRACKED],
         "set the current output width for diagnostic truncation"),
+    packed_bundled_libs: bool = (false, parse_bool, [TRACKED],
+        "change rlib format to store native libraries as archives"),
     panic_abort_tests: bool = (false, parse_bool, [TRACKED],
         "support compiling tests with panic=abort (default: no)"),
     panic_in_drop: PanicStrategy = (PanicStrategy::Unwind, parse_panic_strategy, [TRACKED],
diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs
index ceb6b6c68b0..37b8371a8fe 100644
--- a/compiler/rustc_span/src/def_id.rs
+++ b/compiler/rustc_span/src/def_id.rs
@@ -337,7 +337,7 @@ impl fmt::Debug for DefId {
     }
 }
 
-rustc_data_structures::define_id_collections!(DefIdMap, DefIdSet, DefId);
+rustc_data_structures::define_id_collections!(DefIdMap, DefIdSet, DefIdMapEntry, DefId);
 
 /// A `LocalDefId` is equivalent to a `DefId` with `krate == LOCAL_CRATE`. Since
 /// we encode this information in the type, we can ensure at compile time that
@@ -399,7 +399,12 @@ impl<D: Decoder> Decodable<D> for LocalDefId {
     }
 }
 
-rustc_data_structures::define_id_collections!(LocalDefIdMap, LocalDefIdSet, LocalDefId);
+rustc_data_structures::define_id_collections!(
+    LocalDefIdMap,
+    LocalDefIdSet,
+    LocalDefIdMapEntry,
+    LocalDefId
+);
 
 impl<CTX: HashStableContext> HashStable<CTX> for DefId {
     #[inline]
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index e8ddb4ed17a..191186af6fa 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -944,12 +944,6 @@ pub struct ExpnData {
     /// internally without forcing the whole crate to opt-in
     /// to them.
     pub allow_internal_unstable: Option<Lrc<[Symbol]>>,
-    /// Whether the macro is allowed to use `unsafe` internally
-    /// even if the user crate has `#![forbid(unsafe_code)]`.
-    pub allow_internal_unsafe: bool,
-    /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`)
-    /// for a given macro.
-    pub local_inner_macros: bool,
     /// Edition of the crate in which the macro is defined.
     pub edition: Edition,
     /// The `DefId` of the macro being invoked,
@@ -957,6 +951,13 @@ pub struct ExpnData {
     pub macro_def_id: Option<DefId>,
     /// The normal module (`mod`) in which the expanded macro was defined.
     pub parent_module: Option<DefId>,
+    /// Suppresses the `unsafe_code` lint for code produced by this macro.
+    pub allow_internal_unsafe: bool,
+    /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro.
+    pub local_inner_macros: bool,
+    /// Should debuginfo for the macro be collapsed to the outermost expansion site (in other
+    /// words, was the macro definition annotated with `#[collapse_debuginfo]`)?
+    pub collapse_debuginfo: bool,
 }
 
 impl !PartialEq for ExpnData {}
@@ -969,11 +970,12 @@ impl ExpnData {
         call_site: Span,
         def_site: Span,
         allow_internal_unstable: Option<Lrc<[Symbol]>>,
-        allow_internal_unsafe: bool,
-        local_inner_macros: bool,
         edition: Edition,
         macro_def_id: Option<DefId>,
         parent_module: Option<DefId>,
+        allow_internal_unsafe: bool,
+        local_inner_macros: bool,
+        collapse_debuginfo: bool,
     ) -> ExpnData {
         ExpnData {
             kind,
@@ -981,12 +983,13 @@ impl ExpnData {
             call_site,
             def_site,
             allow_internal_unstable,
-            allow_internal_unsafe,
-            local_inner_macros,
             edition,
             macro_def_id,
             parent_module,
             disambiguator: 0,
+            allow_internal_unsafe,
+            local_inner_macros,
+            collapse_debuginfo,
         }
     }
 
@@ -1004,12 +1007,13 @@ impl ExpnData {
             call_site,
             def_site: DUMMY_SP,
             allow_internal_unstable: None,
-            allow_internal_unsafe: false,
-            local_inner_macros: false,
             edition,
             macro_def_id,
             parent_module,
             disambiguator: 0,
+            allow_internal_unsafe: false,
+            local_inner_macros: false,
+            collapse_debuginfo: false,
         }
     }
 
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 34e2e92bdfc..26b4ebeab1b 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -564,6 +564,13 @@ impl Span {
         self.ctxt() != SyntaxContext::root()
     }
 
+    /// Returns `true` if `span` originates in a macro's expansion where debuginfo should be
+    /// collapsed.
+    pub fn in_macro_expansion_with_collapse_debuginfo(self) -> bool {
+        let outer_expn = self.ctxt().outer_expn_data();
+        matches!(outer_expn.kind, ExpnKind::Macro(..)) && outer_expn.collapse_debuginfo
+    }
+
     /// Returns `true` if `span` originates in a derive-macro's expansion.
     pub fn in_derive_expansion(self) -> bool {
         matches!(self.ctxt().outer_expn_data().kind, ExpnKind::Macro(MacroKind::Derive, _))
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 2d4e2681181..81b0ebfb42c 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -488,6 +488,7 @@ symbols! {
         cmse_nonsecure_entry,
         coerce_unsized,
         cold,
+        collapse_debuginfo,
         column,
         column_macro,
         compare_and_swap,
@@ -1293,6 +1294,7 @@ symbols! {
         rustc_variance,
         rustdoc,
         rustdoc_internals,
+        rustdoc_missing_doc_code_examples,
         rustfmt,
         rvalue_static_promotion,
         s,
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index ecbeb9d79b1..cb605cacc9c 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -1160,8 +1160,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                     // and if not maybe suggest doing something else? If we kept the expression around we
                     // could also check if it is an fn call (very likely) and suggest changing *that*, if
                     // it is from the local crate.
-                    err.span_suggestion_verbose(
-                        expr.span.shrink_to_hi().with_hi(span.hi()),
+                    err.span_suggestion(
+                        span,
                         "remove the `.await`",
                         "",
                         Applicability::MachineApplicable,
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index d9789d5aaf0..95c7e3e39aa 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -2672,7 +2672,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 self.normalize_ty(ast_ty.span, array_ty)
             }
             hir::TyKind::Typeof(ref e) => {
-                let ty = tcx.type_of(tcx.hir().local_def_id(e.hir_id));
+                let ty_erased = tcx.type_of(tcx.hir().local_def_id(e.hir_id));
+                let ty = tcx.fold_regions(ty_erased, |r, _| {
+                    if r.is_erased() { tcx.lifetimes.re_static } else { r }
+                });
                 let span = ast_ty.span;
                 tcx.sess.emit_err(TypeofReservedKeywordUsed {
                     span,
diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs
index 970830045b8..21f80ec025a 100644
--- a/library/core/src/ffi/c_str.rs
+++ b/library/core/src/ffi/c_str.rs
@@ -120,10 +120,10 @@ enum FromBytesWithNulErrorKind {
 }
 
 impl FromBytesWithNulError {
-    fn interior_nul(pos: usize) -> FromBytesWithNulError {
+    const fn interior_nul(pos: usize) -> FromBytesWithNulError {
         FromBytesWithNulError { kind: FromBytesWithNulErrorKind::InteriorNul(pos) }
     }
-    fn not_nul_terminated() -> FromBytesWithNulError {
+    const fn not_nul_terminated() -> FromBytesWithNulError {
         FromBytesWithNulError { kind: FromBytesWithNulErrorKind::NotNulTerminated }
     }
 
@@ -294,7 +294,8 @@ impl CStr {
     /// ```
     ///
     #[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
-    pub fn from_bytes_until_nul(bytes: &[u8]) -> Result<&CStr, FromBytesUntilNulError> {
+    #[rustc_const_unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
+    pub const fn from_bytes_until_nul(bytes: &[u8]) -> Result<&CStr, FromBytesUntilNulError> {
         let nul_pos = memchr::memchr(0, bytes);
         match nul_pos {
             Some(nul_pos) => {
@@ -343,7 +344,8 @@ impl CStr {
     /// assert!(cstr.is_err());
     /// ```
     #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
-    pub fn from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError> {
+    #[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")]
+    pub const fn from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError> {
         let nul_pos = memchr::memchr(0, bytes);
         match nul_pos {
             Some(nul_pos) if nul_pos + 1 == bytes.len() => {
@@ -493,7 +495,8 @@ impl CStr {
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn to_bytes(&self) -> &[u8] {
+    #[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")]
+    pub const fn to_bytes(&self) -> &[u8] {
         let bytes = self.to_bytes_with_nul();
         // SAFETY: to_bytes_with_nul returns slice with length at least 1
         unsafe { bytes.get_unchecked(..bytes.len() - 1) }
@@ -520,7 +523,8 @@ impl CStr {
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn to_bytes_with_nul(&self) -> &[u8] {
+    #[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")]
+    pub const fn to_bytes_with_nul(&self) -> &[u8] {
         // SAFETY: Transmuting a slice of `c_char`s to a slice of `u8`s
         // is safe on all supported targets.
         unsafe { &*(&self.inner as *const [c_char] as *const [u8]) }
@@ -543,7 +547,8 @@ impl CStr {
     /// assert_eq!(cstr.to_str(), Ok("foo"));
     /// ```
     #[stable(feature = "cstr_to_str", since = "1.4.0")]
-    pub fn to_str(&self) -> Result<&str, str::Utf8Error> {
+    #[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")]
+    pub const fn to_str(&self) -> Result<&str, str::Utf8Error> {
         // N.B., when `CStr` is changed to perform the length check in `.to_bytes()`
         // instead of in `from_ptr()`, it may be worth considering if this should
         // be rewritten to do the UTF-8 check inline with the length calculation
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 5b1e2045fff..5621d15c1cd 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -159,6 +159,7 @@
 #![feature(const_slice_from_ref)]
 #![feature(const_slice_index)]
 #![feature(const_is_char_boundary)]
+#![feature(const_cstr_methods)]
 //
 // Language features:
 #![feature(abi_unadjusted)]
diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs
index dffeaf6a834..e0419f0ffdb 100644
--- a/library/core/src/slice/memchr.rs
+++ b/library/core/src/slice/memchr.rs
@@ -2,6 +2,7 @@
 // Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
 
 use crate::cmp;
+use crate::intrinsics;
 use crate::mem;
 
 const LO_USIZE: usize = usize::repeat_u8(0x01);
@@ -35,13 +36,31 @@ fn repeat_byte(b: u8) -> usize {
 /// Returns the first index matching the byte `x` in `text`.
 #[must_use]
 #[inline]
-pub fn memchr(x: u8, text: &[u8]) -> Option<usize> {
-    // Fast path for small slices
-    if text.len() < 2 * USIZE_BYTES {
-        return text.iter().position(|elt| *elt == x);
+pub const fn memchr(x: u8, text: &[u8]) -> Option<usize> {
+    #[inline]
+    fn rt_impl(x: u8, text: &[u8]) -> Option<usize> {
+        // Fast path for small slices
+        if text.len() < 2 * USIZE_BYTES {
+            return text.iter().position(|elt| *elt == x);
+        }
+
+        memchr_general_case(x, text)
+    }
+
+    const fn const_impl(x: u8, bytes: &[u8]) -> Option<usize> {
+        let mut i = 0;
+        while i < bytes.len() {
+            if bytes[i] == x {
+                return Some(i);
+            }
+            i += 1;
+        }
+
+        None
     }
 
-    memchr_general_case(x, text)
+    // SAFETY: The const and runtime versions have identical behavior
+    unsafe { intrinsics::const_eval_select((x, text), const_impl, rt_impl) }
 }
 
 fn memchr_general_case(x: u8, text: &[u8]) -> Option<usize> {
diff --git a/src/librustdoc/lint.rs b/src/librustdoc/lint.rs
index 240aec52cff..e76c19a61c5 100644
--- a/src/librustdoc/lint.rs
+++ b/src/librustdoc/lint.rs
@@ -64,9 +64,13 @@ where
 }
 
 macro_rules! declare_rustdoc_lint {
-    ($(#[$attr:meta])* $name: ident, $level: ident, $descr: literal $(,)?) => {
+    (
+        $(#[$attr:meta])* $name: ident, $level: ident, $descr: literal $(,)?
+        $(@feature_gate = $gate:expr;)?
+    ) => {
         declare_tool_lint! {
             $(#[$attr])* pub rustdoc::$name, $level, $descr
+            $(, @feature_gate = $gate;)?
         }
     }
 }
@@ -123,7 +127,8 @@ declare_rustdoc_lint! {
     /// [rustdoc book]: ../../../rustdoc/lints.html#missing_doc_code_examples
     MISSING_DOC_CODE_EXAMPLES,
     Allow,
-    "detects publicly-exported items without code samples in their documentation"
+    "detects publicly-exported items without code samples in their documentation",
+    @feature_gate = rustc_span::symbol::sym::rustdoc_missing_doc_code_examples;
 }
 
 declare_rustdoc_lint! {
diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs
index e86f9083394..55d5f303d34 100644
--- a/src/librustdoc/passes/check_doc_test_visibility.rs
+++ b/src/librustdoc/passes/check_doc_test_visibility.rs
@@ -117,7 +117,7 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item
 
     find_testable_code(dox, &mut tests, ErrorCodes::No, false, None);
 
-    if tests.found_tests == 0 && cx.tcx.sess.is_nightly_build() {
+    if tests.found_tests == 0 && cx.tcx.features().rustdoc_missing_doc_code_examples {
         if should_have_doc_example(cx, item) {
             debug!("reporting error for {:?} (hir_id={:?})", item, hir_id);
             let sp = item.attr_span(cx.tcx);
diff --git a/src/librustdoc/passes/html_tags.rs b/src/librustdoc/passes/html_tags.rs
index f3a3c853cac..885dadb32a8 100644
--- a/src/librustdoc/passes/html_tags.rs
+++ b/src/librustdoc/passes/html_tags.rs
@@ -94,6 +94,34 @@ fn extract_path_backwards(text: &str, end_pos: usize) -> Option<usize> {
     if current_pos == end_pos { None } else { Some(current_pos) }
 }
 
+fn extract_path_forward(text: &str, start_pos: usize) -> Option<usize> {
+    use rustc_lexer::{is_id_continue, is_id_start};
+    let mut current_pos = start_pos;
+    loop {
+        if current_pos < text.len() && text[current_pos..].starts_with("::") {
+            current_pos += 2;
+        } else {
+            break;
+        }
+        let mut chars = text[current_pos..].chars();
+        if let Some(c) = chars.next() {
+            if is_id_start(c) {
+                current_pos += c.len_utf8();
+            } else {
+                break;
+            }
+        }
+        while let Some(c) = chars.next() {
+            if is_id_continue(c) {
+                current_pos += c.len_utf8();
+            } else {
+                break;
+            }
+        }
+    }
+    if current_pos == start_pos { None } else { Some(current_pos) }
+}
+
 fn is_valid_for_html_tag_name(c: char, is_empty: bool) -> bool {
     // https://spec.commonmark.org/0.30/#raw-html
     //
@@ -218,19 +246,68 @@ impl<'a, 'tcx> DocVisitor for InvalidHtmlTagsLinter<'a, 'tcx> {
                     // If a tag looks like `<this>`, it might actually be a generic.
                     // We don't try to detect stuff `<like, this>` because that's not valid HTML,
                     // and we don't try to detect stuff `<like this>` because that's not valid Rust.
-                    if let Some(Some(generics_start)) = (is_open_tag
-                        && dox[..range.end].ends_with('>'))
+                    let mut generics_end = range.end;
+                    if let Some(Some(mut generics_start)) = (is_open_tag
+                        && dox[..generics_end].ends_with('>'))
                     .then(|| extract_path_backwards(&dox, range.start))
                     {
+                        while generics_start != 0
+                            && generics_end < dox.len()
+                            && dox.as_bytes()[generics_start - 1] == b'<'
+                            && dox.as_bytes()[generics_end] == b'>'
+                        {
+                            generics_end += 1;
+                            generics_start -= 1;
+                            if let Some(new_start) = extract_path_backwards(&dox, generics_start) {
+                                generics_start = new_start;
+                            }
+                            if let Some(new_end) = extract_path_forward(&dox, generics_end) {
+                                generics_end = new_end;
+                            }
+                        }
+                        if let Some(new_end) = extract_path_forward(&dox, generics_end) {
+                            generics_end = new_end;
+                        }
                         let generics_sp = match super::source_span_for_markdown_range(
                             tcx,
                             &dox,
-                            &(generics_start..range.end),
+                            &(generics_start..generics_end),
                             &item.attrs,
                         ) {
                             Some(sp) => sp,
                             None => item.attr_span(tcx),
                         };
+                        // Sometimes, we only extract part of a path. For example, consider this:
+                        //
+                        //     <[u32] as IntoIter<u32>>::Item
+                        //                       ^^^^^ unclosed HTML tag `u32`
+                        //
+                        // We don't have any code for parsing fully-qualified trait paths.
+                        // In theory, we could add it, but doing it correctly would require
+                        // parsing the entire path grammar, which is problematic because of
+                        // overlap between the path grammar and Markdown.
+                        //
+                        // The example above shows that ambiguity. Is `[u32]` intended to be an
+                        // intra-doc link to the u32 primitive, or is it intended to be a slice?
+                        //
+                        // If the below conditional were removed, we would suggest this, which is
+                        // not what the user probably wants.
+                        //
+                        //     <[u32] as `IntoIter<u32>`>::Item
+                        //
+                        // We know that the user actually wants to wrap the whole thing in a code
+                        // block, but the only reason we know that is because `u32` does not, in
+                        // fact, implement IntoIter. If the example looks like this:
+                        //
+                        //     <[Vec<i32>] as IntoIter<i32>::Item
+                        //
+                        // The ideal fix would be significantly different.
+                        if (generics_start > 0 && dox.as_bytes()[generics_start - 1] == b'<')
+                            || (generics_end < dox.len() && dox.as_bytes()[generics_end] == b'>')
+                        {
+                            diag.emit();
+                            return;
+                        }
                         // multipart form is chosen here because ``Vec<i32>`` would be confusing.
                         diag.multipart_suggestion(
                             "try marking as source code",
@@ -278,7 +355,7 @@ impl<'a, 'tcx> DocVisitor for InvalidHtmlTagsLinter<'a, 'tcx> {
             for (event, range) in p {
                 match event {
                     Event::Start(Tag::CodeBlock(_)) => in_code_block = true,
-                    Event::Html(text) | Event::Text(text) if !in_code_block => {
+                    Event::Html(text) if !in_code_block => {
                         extract_tags(&mut tags, &text, range, &mut is_in_comment, &report_diag)
                     }
                     Event::End(Tag::CodeBlock(_)) => in_code_block = false,
diff --git a/src/test/debuginfo/collapse-debuginfo-no-attr-flag.rs b/src/test/debuginfo/collapse-debuginfo-no-attr-flag.rs
new file mode 100644
index 00000000000..413f6120105
--- /dev/null
+++ b/src/test/debuginfo/collapse-debuginfo-no-attr-flag.rs
@@ -0,0 +1,61 @@
+// ignore-lldb
+#![feature(collapse_debuginfo)]
+
+// Test that line numbers are not replaced with those of the outermost expansion site when the
+// `collapse_debuginfo` is active, `-Zdebug-macros` is provided and `#[collapse_debuginfo]` not
+// being used.
+
+// compile-flags:-g -Zdebug-macros
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command:run
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc1[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc2[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc3[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc4[...]
+// gdb-command:continue
+
+fn one() {
+    println!("one");
+}
+fn two() {
+    println!("two");
+}
+fn three() {
+    println!("three");
+}
+fn four() {
+    println!("four");
+}
+
+macro_rules! outer {
+    ($b:block) => {
+        one(); // #loc1
+        inner!();
+        $b
+    };
+}
+
+macro_rules! inner {
+    () => {
+        two(); // #loc2
+    };
+}
+
+fn main() {
+    let ret = 0; // #break
+    outer!({
+        three(); // #loc3
+        four(); // #loc4
+    });
+    std::process::exit(ret);
+}
diff --git a/src/test/debuginfo/collapse-debuginfo-no-attr.rs b/src/test/debuginfo/collapse-debuginfo-no-attr.rs
new file mode 100644
index 00000000000..230c8795be3
--- /dev/null
+++ b/src/test/debuginfo/collapse-debuginfo-no-attr.rs
@@ -0,0 +1,60 @@
+// ignore-lldb
+#![feature(collapse_debuginfo)]
+
+// Test that line numbers are not replaced with those of the outermost expansion site when the
+// `collapse_debuginfo` feature is active and the attribute is not provided.
+
+// compile-flags:-g
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command:run
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc1[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc2[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc3[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc4[...]
+// gdb-command:continue
+
+fn one() {
+    println!("one");
+}
+fn two() {
+    println!("two");
+}
+fn three() {
+    println!("three");
+}
+fn four() {
+    println!("four");
+}
+
+macro_rules! outer {
+    ($b:block) => {
+        one(); // #loc1
+        inner!();
+        $b
+    };
+}
+
+macro_rules! inner {
+    () => {
+        two(); // #loc2
+    };
+}
+
+fn main() {
+    let ret = 0; // #break
+    outer!({
+        three(); // #loc3
+        four(); // #loc4
+    });
+    std::process::exit(ret);
+}
diff --git a/src/test/debuginfo/collapse-debuginfo-with-attr-flag.rs b/src/test/debuginfo/collapse-debuginfo-with-attr-flag.rs
new file mode 100644
index 00000000000..183cf537e85
--- /dev/null
+++ b/src/test/debuginfo/collapse-debuginfo-with-attr-flag.rs
@@ -0,0 +1,63 @@
+// ignore-lldb
+#![feature(collapse_debuginfo)]
+
+// Test that line numbers are not replaced with those of the outermost expansion site when the
+// `collapse_debuginfo` is active and `-Zdebug-macros` is provided, despite `#[collapse_debuginfo]`
+// being used.
+
+// compile-flags:-g -Zdebug-macros
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command:run
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc1[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc2[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc3[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc4[...]
+// gdb-command:continue
+
+fn one() {
+    println!("one");
+}
+fn two() {
+    println!("two");
+}
+fn three() {
+    println!("three");
+}
+fn four() {
+    println!("four");
+}
+
+#[collapse_debuginfo]
+macro_rules! outer {
+    ($b:block) => {
+        one(); // #loc1
+        inner!();
+        $b
+    };
+}
+
+#[collapse_debuginfo]
+macro_rules! inner {
+    () => {
+        two(); // #loc2
+    };
+}
+
+fn main() {
+    let ret = 0; // #break
+    outer!({
+        three(); // #loc3
+        four(); // #loc4
+    });
+    std::process::exit(ret);
+}
diff --git a/src/test/debuginfo/collapse-debuginfo-with-attr.rs b/src/test/debuginfo/collapse-debuginfo-with-attr.rs
new file mode 100644
index 00000000000..34d03c18bc7
--- /dev/null
+++ b/src/test/debuginfo/collapse-debuginfo-with-attr.rs
@@ -0,0 +1,59 @@
+// ignore-lldb
+#![feature(collapse_debuginfo)]
+
+// Test that line numbers are replaced with those of the outermost expansion site when the
+// `collapse_debuginfo` feature is active and the attribute is provided.
+
+// compile-flags:-g
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command:run
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc1[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc2[...]
+// gdb-command:next
+// gdb-command:frame
+// gdb-check:[...]#loc3[...]
+// gdb-command:continue
+
+fn one() {
+    println!("one");
+}
+fn two() {
+    println!("two");
+}
+fn three() {
+    println!("three");
+}
+fn four() {
+    println!("four");
+}
+
+#[collapse_debuginfo]
+macro_rules! outer {
+    ($b:block) => {
+        one();
+        inner!();
+        $b
+    };
+}
+
+#[collapse_debuginfo]
+macro_rules! inner {
+    () => {
+        two();
+    };
+}
+
+fn main() {
+    let ret = 0; // #break
+    outer!({ // #loc1
+        three(); // #loc2
+        four(); // #loc3
+    });
+    std::process::exit(ret);
+}
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs-2/Makefile b/src/test/run-make/rlib-format-packed-bundled-libs-2/Makefile
new file mode 100644
index 00000000000..4574cf17f0e
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs-2/Makefile
@@ -0,0 +1,22 @@
+-include ../../run-make-fulldeps/tools.mk
+
+# ignore-cross-compile
+
+# Make sure -Zpacked_bundled_libs is compatible with verbatim.
+
+# We're using the llvm-nm instead of the system nm to ensure it is compatible
+# with the LLVM bitcode generated by rustc.
+NM = "$(LLVM_BIN_DIR)"/llvm-nm
+
+all:
+	# Build strange-named dep.
+	$(RUSTC) native_dep.rs --crate-type=staticlib -o $(TMPDIR)/native_dep.ext
+
+	$(RUSTC) rust_dep.rs --crate-type=rlib -Zpacked_bundled_libs
+	$(NM) $(TMPDIR)/librust_dep.rlib | $(CGREP) -e "U.*native_f1"
+	$(AR) t $(TMPDIR)/librust_dep.rlib | $(CGREP) "native_dep.ext"
+
+	# Make sure compiler doesn't use files, that it shouldn't know about.
+	rm $(TMPDIR)/native_dep.ext
+
+	$(RUSTC) main.rs --extern rust_dep=$(TMPDIR)/librust_dep.rlib -Zpacked_bundled_libs
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs-2/main.rs b/src/test/run-make/rlib-format-packed-bundled-libs-2/main.rs
new file mode 100644
index 00000000000..8d2b8a2859c
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs-2/main.rs
@@ -0,0 +1,5 @@
+extern crate rust_dep;
+
+pub fn main() {
+    rust_dep::rust_dep();
+}
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs-2/native_dep.rs b/src/test/run-make/rlib-format-packed-bundled-libs-2/native_dep.rs
new file mode 100644
index 00000000000..321a8237e8a
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs-2/native_dep.rs
@@ -0,0 +1,4 @@
+#[no_mangle]
+pub fn native_f1() -> i32 {
+    return 1;
+}
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs-2/rust_dep.rs b/src/test/run-make/rlib-format-packed-bundled-libs-2/rust_dep.rs
new file mode 100644
index 00000000000..d99dda05cf2
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs-2/rust_dep.rs
@@ -0,0 +1,11 @@
+#![feature(native_link_modifiers_verbatim)]
+#[link(name = "native_dep.ext", kind = "static", modifiers = "+verbatim")]
+extern "C" {
+    fn native_f1() -> i32;
+}
+
+pub fn rust_dep() {
+    unsafe {
+        assert!(native_f1() == 1);
+    }
+}
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs/Makefile b/src/test/run-make/rlib-format-packed-bundled-libs/Makefile
new file mode 100644
index 00000000000..0b991ac42e3
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs/Makefile
@@ -0,0 +1,34 @@
+-include ../../run-make-fulldeps/tools.mk
+
+# ignore-cross-compile
+
+# Make sure rlib format with -Zpacked_bundled_libs is correct.
+
+# We're using the llvm-nm instead of the system nm to ensure it is compatible
+# with the LLVM bitcode generated by rustc.
+NM = "$(LLVM_BIN_DIR)"/llvm-nm
+
+all: $(call NATIVE_STATICLIB,native_dep_1) $(call NATIVE_STATICLIB,native_dep_2) $(call NATIVE_STATICLIB,native_dep_3)
+	$(RUSTC) rust_dep_up.rs --crate-type=rlib -Zpacked_bundled_libs
+	$(NM) $(TMPDIR)/librust_dep_up.rlib | $(CGREP) -e "U.*native_f2"
+	$(NM) $(TMPDIR)/librust_dep_up.rlib | $(CGREP) -e "U.*native_f3"
+	$(NM) $(TMPDIR)/librust_dep_up.rlib | $(CGREP) -e "T.*rust_dep_up"
+	$(AR) t $(TMPDIR)/librust_dep_up.rlib | $(CGREP) "native_dep_2"
+	$(AR) t $(TMPDIR)/librust_dep_up.rlib | $(CGREP) "native_dep_3"
+	$(RUSTC) rust_dep_local.rs --extern rlib=$(TMPDIR)/librust_dep_up.rlib -Zpacked_bundled_libs --crate-type=rlib
+	$(NM) $(TMPDIR)/librust_dep_local.rlib | $(CGREP) -e "U.*native_f1"
+	$(NM) $(TMPDIR)/librust_dep_local.rlib | $(CGREP) -e "T.*rust_dep_local"
+	$(AR) t $(TMPDIR)/librust_dep_local.rlib | $(CGREP) "native_dep_1"
+
+	# Make sure compiler doesn't use files, that it shouldn't know about.
+	rm $(TMPDIR)/*native_dep_*
+
+	$(RUSTC) main.rs --extern lib=$(TMPDIR)/librust_dep_local.rlib -o $(TMPDIR)/main.exe -Zpacked_bundled_libs --print link-args | $(CGREP) -e "native_dep_1.*native_dep_2.*native_dep_3"
+
+ifndef IS_MSVC
+	$(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*native_f1"
+	$(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*native_f2"
+	$(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*native_f3"
+	$(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*rust_dep_local"
+	$(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*rust_dep_up"
+endif
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs/main.rs b/src/test/run-make/rlib-format-packed-bundled-libs/main.rs
new file mode 100644
index 00000000000..042a4879fe4
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs/main.rs
@@ -0,0 +1,4 @@
+extern crate rust_dep_local;
+pub fn main() {
+    rust_dep_local::rust_dep_local();
+}
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_1.c b/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_1.c
new file mode 100644
index 00000000000..07be8562c92
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_1.c
@@ -0,0 +1 @@
+int native_f1() { return 1; }
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_2.c b/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_2.c
new file mode 100644
index 00000000000..a1b94e40dc0
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_2.c
@@ -0,0 +1 @@
+int native_f2() { return 2; }
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_3.c b/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_3.c
new file mode 100644
index 00000000000..f81f397a4b1
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_3.c
@@ -0,0 +1 @@
+int native_f3() { return 3; }
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_local.rs b/src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_local.rs
new file mode 100644
index 00000000000..8280c7d6c51
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_local.rs
@@ -0,0 +1,13 @@
+#[link(name = "native_dep_1", kind = "static")]
+extern "C" {
+    fn native_f1() -> i32;
+}
+
+extern crate rust_dep_up;
+
+pub fn rust_dep_local() {
+    unsafe {
+        assert!(native_f1() == 1);
+    }
+    rust_dep_up::rust_dep_up();
+}
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_up.rs b/src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_up.rs
new file mode 100644
index 00000000000..edcd7c52129
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_up.rs
@@ -0,0 +1,13 @@
+#[link(name = "native_dep_2", kind = "static")]
+#[link(name = "native_dep_3", kind = "static")]
+extern "C" {
+    fn native_f2() -> i32;
+    fn native_f3() -> i32;
+}
+
+pub fn rust_dep_up() {
+    unsafe {
+        assert!(native_f2() == 2);
+        assert!(native_f3() == 3);
+    }
+}
diff --git a/src/test/rustdoc-ui/check-fail.rs b/src/test/rustdoc-ui/check-fail.rs
index 2355d6a3d6c..c5e1759ee2d 100644
--- a/src/test/rustdoc-ui/check-fail.rs
+++ b/src/test/rustdoc-ui/check-fail.rs
@@ -1,5 +1,6 @@
 // compile-flags: -Z unstable-options --check
 
+#![feature(rustdoc_missing_doc_code_examples)]
 #![deny(missing_docs)]
 #![deny(rustdoc::all)]
 
diff --git a/src/test/rustdoc-ui/check-fail.stderr b/src/test/rustdoc-ui/check-fail.stderr
index 5d46dc72014..217b89d935b 100644
--- a/src/test/rustdoc-ui/check-fail.stderr
+++ b/src/test/rustdoc-ui/check-fail.stderr
@@ -1,30 +1,30 @@
 error: missing documentation for a function
-  --> $DIR/check-fail.rs:11:1
+  --> $DIR/check-fail.rs:12:1
    |
 LL | pub fn foo() {}
    | ^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/check-fail.rs:3:9
+  --> $DIR/check-fail.rs:4:9
    |
 LL | #![deny(missing_docs)]
    |         ^^^^^^^^^^^^
 
 error: missing code example in this documentation
-  --> $DIR/check-fail.rs:11:1
+  --> $DIR/check-fail.rs:12:1
    |
 LL | pub fn foo() {}
    | ^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/check-fail.rs:4:9
+  --> $DIR/check-fail.rs:5:9
    |
 LL | #![deny(rustdoc::all)]
    |         ^^^^^^^^^^^^
    = note: `#[deny(rustdoc::missing_doc_code_examples)]` implied by `#[deny(rustdoc::all)]`
 
 error: unknown attribute `testharness`. Did you mean `test_harness`?
-  --> $DIR/check-fail.rs:6:1
+  --> $DIR/check-fail.rs:7:1
    |
 LL | / //! ```rust,testharness
 LL | |
@@ -36,7 +36,7 @@ LL | | //! ```
    = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
 
 error: unknown attribute `testharness`. Did you mean `test_harness`?
-  --> $DIR/check-fail.rs:15:1
+  --> $DIR/check-fail.rs:16:1
    |
 LL | / /// hello
 LL | |
diff --git a/src/test/rustdoc-ui/check.rs b/src/test/rustdoc-ui/check.rs
index 2b44ba24b44..f70b0336151 100644
--- a/src/test/rustdoc-ui/check.rs
+++ b/src/test/rustdoc-ui/check.rs
@@ -2,9 +2,11 @@
 // compile-flags: -Z unstable-options --check
 // normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL"
 
-#![warn(missing_docs)]
+#![feature(rustdoc_missing_doc_code_examples)]
 //~^ WARN
 //~^^ WARN
+
+#![warn(missing_docs)]
 #![warn(rustdoc::all)]
 
 pub fn foo() {}
diff --git a/src/test/rustdoc-ui/check.stderr b/src/test/rustdoc-ui/check.stderr
index 06e607fbe55..78ae65d313a 100644
--- a/src/test/rustdoc-ui/check.stderr
+++ b/src/test/rustdoc-ui/check.stderr
@@ -1,22 +1,23 @@
 warning: missing documentation for the crate
   --> $DIR/check.rs:5:1
    |
-LL | / #![warn(missing_docs)]
+LL | / #![feature(rustdoc_missing_doc_code_examples)]
 LL | |
 LL | |
-LL | | #![warn(rustdoc::all)]
+LL | |
+...  |
 LL | |
 LL | | pub fn foo() {}
    | |_______________^
    |
 note: the lint level is defined here
-  --> $DIR/check.rs:5:9
+  --> $DIR/check.rs:9:9
    |
 LL | #![warn(missing_docs)]
    |         ^^^^^^^^^^^^
 
 warning: missing documentation for a function
-  --> $DIR/check.rs:10:1
+  --> $DIR/check.rs:12:1
    |
 LL | pub fn foo() {}
    | ^^^^^^^^^^^^
@@ -24,7 +25,7 @@ LL | pub fn foo() {}
 warning: no documentation found for this crate's top-level module
    |
 note: the lint level is defined here
-  --> $DIR/check.rs:8:9
+  --> $DIR/check.rs:10:9
    |
 LL | #![warn(rustdoc::all)]
    |         ^^^^^^^^^^^^
@@ -35,10 +36,11 @@ LL | #![warn(rustdoc::all)]
 warning: missing code example in this documentation
   --> $DIR/check.rs:5:1
    |
-LL | / #![warn(missing_docs)]
+LL | / #![feature(rustdoc_missing_doc_code_examples)]
+LL | |
 LL | |
 LL | |
-LL | | #![warn(rustdoc::all)]
+...  |
 LL | |
 LL | | pub fn foo() {}
    | |_______________^
@@ -46,7 +48,7 @@ LL | | pub fn foo() {}
    = note: `#[warn(rustdoc::missing_doc_code_examples)]` implied by `#[warn(rustdoc::all)]`
 
 warning: missing code example in this documentation
-  --> $DIR/check.rs:10:1
+  --> $DIR/check.rs:12:1
    |
 LL | pub fn foo() {}
    | ^^^^^^^^^^^^^^^
diff --git a/src/test/rustdoc-ui/doc-without-codeblock.rs b/src/test/rustdoc-ui/doc-without-codeblock.rs
index 315fca19587..86d7c83d335 100644
--- a/src/test/rustdoc-ui/doc-without-codeblock.rs
+++ b/src/test/rustdoc-ui/doc-without-codeblock.rs
@@ -1,4 +1,5 @@
-#![deny(rustdoc::missing_doc_code_examples)] //~ ERROR missing code example in this documentation
+#![feature(rustdoc_missing_doc_code_examples)] //~ ERROR missing code example in this documentation
+#![deny(rustdoc::missing_doc_code_examples)]
 
 /// Some docs.
 //~^ ERROR missing code example in this documentation
diff --git a/src/test/rustdoc-ui/doc-without-codeblock.stderr b/src/test/rustdoc-ui/doc-without-codeblock.stderr
index 1c138044165..ebf2a2d54f7 100644
--- a/src/test/rustdoc-ui/doc-without-codeblock.stderr
+++ b/src/test/rustdoc-ui/doc-without-codeblock.stderr
@@ -1,35 +1,35 @@
 error: missing code example in this documentation
   --> $DIR/doc-without-codeblock.rs:1:1
    |
-LL | / #![deny(rustdoc::missing_doc_code_examples)]
+LL | / #![feature(rustdoc_missing_doc_code_examples)]
+LL | | #![deny(rustdoc::missing_doc_code_examples)]
 LL | |
 LL | | /// Some docs.
-LL | |
 ...  |
 LL | |     }
 LL | | }
    | |_^
    |
 note: the lint level is defined here
-  --> $DIR/doc-without-codeblock.rs:1:9
+  --> $DIR/doc-without-codeblock.rs:2:9
    |
 LL | #![deny(rustdoc::missing_doc_code_examples)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: missing code example in this documentation
-  --> $DIR/doc-without-codeblock.rs:7:1
+  --> $DIR/doc-without-codeblock.rs:8:1
    |
 LL | /// And then, the princess died.
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: missing code example in this documentation
-  --> $DIR/doc-without-codeblock.rs:10:5
+  --> $DIR/doc-without-codeblock.rs:11:5
    |
 LL |     /// Or maybe not because she saved herself!
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: missing code example in this documentation
-  --> $DIR/doc-without-codeblock.rs:3:1
+  --> $DIR/doc-without-codeblock.rs:4:1
    |
 LL | /// Some docs.
    | ^^^^^^^^^^^^^^
diff --git a/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.rs b/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.rs
new file mode 100644
index 00000000000..daba6986864
--- /dev/null
+++ b/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.rs
@@ -0,0 +1,10 @@
+#![deny(unknown_lints)]
+//~^ NOTE defined here
+
+#![allow(rustdoc::missing_doc_code_examples)]
+//~^ ERROR unknown lint
+//~| ERROR unknown lint
+//~| NOTE lint is unstable
+//~| NOTE lint is unstable
+//~| NOTE see issue
+//~| NOTE see issue
diff --git a/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.stderr b/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.stderr
new file mode 100644
index 00000000000..517e08aa7c9
--- /dev/null
+++ b/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.stderr
@@ -0,0 +1,29 @@
+error: unknown lint: `rustdoc::missing_doc_code_examples`
+  --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:4:1
+   |
+LL | #![allow(rustdoc::missing_doc_code_examples)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:1:9
+   |
+LL | #![deny(unknown_lints)]
+   |         ^^^^^^^^^^^^^
+   = note: the `rustdoc::missing_doc_code_examples` lint is unstable
+   = note: see issue #101730 <https://github.com/rust-lang/rust/issues/101730> for more information
+   = help: add `#![feature(rustdoc_missing_doc_code_examples)]` to the crate attributes to enable
+
+error: unknown lint: `rustdoc::missing_doc_code_examples`
+  --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:4:1
+   |
+LL | #![allow(rustdoc::missing_doc_code_examples)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the `rustdoc::missing_doc_code_examples` lint is unstable
+   = note: see issue #101730 <https://github.com/rust-lang/rust/issues/101730> for more information
+   = help: add `#![feature(rustdoc_missing_doc_code_examples)]` to the crate attributes to enable
+
+error: Compilation failed, aborting rustdoc
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/rustdoc-ui/invalid-html-tags.rs b/src/test/rustdoc-ui/invalid-html-tags.rs
index 0f9d2e4b35d..317f1fd1d46 100644
--- a/src/test/rustdoc-ui/invalid-html-tags.rs
+++ b/src/test/rustdoc-ui/invalid-html-tags.rs
@@ -114,3 +114,10 @@ pub fn k() {}
 /// Web Components style </unopened-tag>
 //~^ ERROR unopened HTML tag `unopened-tag`
 pub fn m() {}
+
+/// backslashed \<a href="">
+pub fn no_error_1() {}
+
+/// backslashed \<<a href="">
+//~^ ERROR unclosed HTML tag `a`
+pub fn p() {}
diff --git a/src/test/rustdoc-ui/invalid-html-tags.stderr b/src/test/rustdoc-ui/invalid-html-tags.stderr
index 24a455576e8..9c2bfcf2c3d 100644
--- a/src/test/rustdoc-ui/invalid-html-tags.stderr
+++ b/src/test/rustdoc-ui/invalid-html-tags.stderr
@@ -94,5 +94,11 @@ error: unclosed HTML tag `dashed-tags`
 LL | /// Web Components style <dashed-tags>
    |                          ^^^^^^^^^^^^^
 
-error: aborting due to 15 previous errors
+error: unclosed HTML tag `a`
+  --> $DIR/invalid-html-tags.rs:121:19
+   |
+LL | /// backslashed \<<a href="">
+   |                   ^^
+
+error: aborting due to 16 previous errors
 
diff --git a/src/test/rustdoc-ui/lint-group.rs b/src/test/rustdoc-ui/lint-group.rs
index 61555a6e686..09aca6d2b27 100644
--- a/src/test/rustdoc-ui/lint-group.rs
+++ b/src/test/rustdoc-ui/lint-group.rs
@@ -1,3 +1,5 @@
+#![feature(rustdoc_missing_doc_code_examples)]
+
 //! Documenting the kinds of lints emitted by rustdoc.
 //!
 //! ```
diff --git a/src/test/rustdoc-ui/lint-group.stderr b/src/test/rustdoc-ui/lint-group.stderr
index e28600160b1..5336c044574 100644
--- a/src/test/rustdoc-ui/lint-group.stderr
+++ b/src/test/rustdoc-ui/lint-group.stderr
@@ -1,18 +1,18 @@
 error: missing code example in this documentation
-  --> $DIR/lint-group.rs:16:1
+  --> $DIR/lint-group.rs:18:1
    |
 LL | /// wait, this doesn't have a doctest?
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/lint-group.rs:7:9
+  --> $DIR/lint-group.rs:9:9
    |
 LL | #![deny(rustdoc::all)]
    |         ^^^^^^^^^^^^
    = note: `#[deny(rustdoc::missing_doc_code_examples)]` implied by `#[deny(rustdoc::all)]`
 
 error: documentation test in private item
-  --> $DIR/lint-group.rs:19:1
+  --> $DIR/lint-group.rs:21:1
    |
 LL | / /// wait, this *does* have a doctest?
 LL | | ///
@@ -24,13 +24,13 @@ LL | | /// ```
    = note: `#[deny(rustdoc::private_doc_tests)]` implied by `#[deny(rustdoc::all)]`
 
 error: missing code example in this documentation
-  --> $DIR/lint-group.rs:26:1
+  --> $DIR/lint-group.rs:28:1
    |
 LL | /// <unknown>
    | ^^^^^^^^^^^^^
 
 error: unresolved link to `error`
-  --> $DIR/lint-group.rs:9:29
+  --> $DIR/lint-group.rs:11:29
    |
 LL | /// what up, let's make an [error]
    |                             ^^^^^ no item named `error` in scope
@@ -39,7 +39,7 @@ LL | /// what up, let's make an [error]
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 error: unclosed HTML tag `unknown`
-  --> $DIR/lint-group.rs:26:5
+  --> $DIR/lint-group.rs:28:5
    |
 LL | /// <unknown>
    |     ^^^^^^^^^
diff --git a/src/test/rustdoc-ui/lint-missing-doc-code-example.rs b/src/test/rustdoc-ui/lint-missing-doc-code-example.rs
index fac6342cd24..40f35728d79 100644
--- a/src/test/rustdoc-ui/lint-missing-doc-code-example.rs
+++ b/src/test/rustdoc-ui/lint-missing-doc-code-example.rs
@@ -1,3 +1,4 @@
+#![feature(rustdoc_missing_doc_code_examples)]
 #![deny(missing_docs)]
 #![deny(rustdoc::missing_doc_code_examples)]
 
diff --git a/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr b/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr
index 9e51ecd2ba0..f9331250154 100644
--- a/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr
+++ b/src/test/rustdoc-ui/lint-missing-doc-code-example.stderr
@@ -1,35 +1,35 @@
 error: missing code example in this documentation
-  --> $DIR/lint-missing-doc-code-example.rs:19:1
+  --> $DIR/lint-missing-doc-code-example.rs:20:1
    |
 LL | pub mod module1 {
    | ^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/lint-missing-doc-code-example.rs:2:9
+  --> $DIR/lint-missing-doc-code-example.rs:3:9
    |
 LL | #![deny(rustdoc::missing_doc_code_examples)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: missing code example in this documentation
-  --> $DIR/lint-missing-doc-code-example.rs:37:3
+  --> $DIR/lint-missing-doc-code-example.rs:38:3
    |
 LL |   /// doc
    |   ^^^^^^^
 
 error: missing code example in this documentation
-  --> $DIR/lint-missing-doc-code-example.rs:49:1
+  --> $DIR/lint-missing-doc-code-example.rs:50:1
    |
 LL | /// Doc
    | ^^^^^^^
 
 error: missing code example in this documentation
-  --> $DIR/lint-missing-doc-code-example.rs:56:1
+  --> $DIR/lint-missing-doc-code-example.rs:57:1
    |
 LL | /// Doc
    | ^^^^^^^
 
 error: missing code example in this documentation
-  --> $DIR/lint-missing-doc-code-example.rs:63:1
+  --> $DIR/lint-missing-doc-code-example.rs:64:1
    |
 LL | /// Doc
    | ^^^^^^^
diff --git a/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.rs b/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.rs
index 744b3071f1b..476e3b2d43e 100644
--- a/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.rs
+++ b/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.rs
@@ -8,6 +8,48 @@ pub struct ConstGeneric;
 // HTML tags cannot contain commas, so no error.
 pub struct MultipleGenerics;
 
+/// This <[u32] as Iterator<Item>> thing!
+//~^ERROR unclosed HTML tag `Item`
+// Some forms of fully-qualified path are simultaneously valid HTML tags
+// with attributes. They produce an error, but no suggestion, because figuring
+// out if this is valid would require parsing the entire path grammar.
+//
+// The important part is that we don't produce any *wrong* suggestions.
+// While several other examples below are added to make sure we don't
+// produce suggestions when given complex paths, this example is the actual
+// reason behind not just using the real path parser. It's ambiguous: there's
+// no way to locally reason out whether that `[u32]` is intended to be a slice
+// or an intra-doc link.
+pub struct FullyQualifiedPathsDoNotCount;
+
+/// This <Vec as IntoIter>::Iter thing!
+//~^ERROR unclosed HTML tag `Vec`
+// Some forms of fully-qualified path are simultaneously valid HTML tags
+// with attributes. They produce an error, but no suggestion, because figuring
+// out if this is valid would require parsing the entire path grammar.
+pub struct FullyQualifiedPathsDoNotCount1;
+
+/// This Vec<Vec as IntoIter>::Iter thing!
+//~^ERROR unclosed HTML tag `Vec`
+// Some forms of fully-qualified path are simultaneously valid HTML tags
+// with attributes. They produce an error, but no suggestion, because figuring
+// out if this is valid would require parsing the entire path grammar.
+pub struct FullyQualifiedPathsDoNotCount2;
+
+/// This Vec<Vec as IntoIter> thing!
+//~^ERROR unclosed HTML tag `Vec`
+// Some forms of fully-qualified path are simultaneously valid HTML tags
+// with attributes. They produce an error, but no suggestion, because figuring
+// out if this is valid would require parsing the entire path grammar.
+pub struct FullyQualifiedPathsDoNotCount3;
+
+/// This Vec<Vec<i32> as IntoIter> thing!
+//~^ERROR unclosed HTML tag `i32`
+// Some forms of fully-qualified path are simultaneously valid HTML tags
+// with attributes. They produce an error, but no suggestion, because figuring
+// out if this is valid would require parsing the entire path grammar.
+pub struct FullyQualifiedPathsDoNotCount4;
+
 /// This Vec<i32 class="test"> thing!
 //~^ERROR unclosed HTML tag `i32`
 // HTML attributes shouldn't be treated as Rust syntax, so no suggestions.
diff --git a/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.stderr b/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.stderr
index 832b8b2cac7..3856a251321 100644
--- a/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.stderr
+++ b/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.stderr
@@ -1,8 +1,8 @@
-error: unclosed HTML tag `i32`
-  --> $DIR/html-as-generics-no-suggestions.rs:11:13
+error: unclosed HTML tag `Item`
+  --> $DIR/html-as-generics-no-suggestions.rs:11:28
    |
-LL | /// This Vec<i32 class="test"> thing!
-   |             ^^^^
+LL | /// This <[u32] as Iterator<Item>> thing!
+   |                            ^^^^^^
    |
 note: the lint level is defined here
   --> $DIR/html-as-generics-no-suggestions.rs:1:9
@@ -10,29 +10,59 @@ note: the lint level is defined here
 LL | #![deny(rustdoc::invalid_html_tags)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+error: unclosed HTML tag `Vec`
+  --> $DIR/html-as-generics-no-suggestions.rs:25:10
+   |
+LL | /// This <Vec as IntoIter>::Iter thing!
+   |          ^^^^
+
+error: unclosed HTML tag `Vec`
+  --> $DIR/html-as-generics-no-suggestions.rs:32:13
+   |
+LL | /// This Vec<Vec as IntoIter>::Iter thing!
+   |             ^^^^
+
+error: unclosed HTML tag `Vec`
+  --> $DIR/html-as-generics-no-suggestions.rs:39:13
+   |
+LL | /// This Vec<Vec as IntoIter> thing!
+   |             ^^^^
+
+error: unclosed HTML tag `i32`
+  --> $DIR/html-as-generics-no-suggestions.rs:46:17
+   |
+LL | /// This Vec<Vec<i32> as IntoIter> thing!
+   |                 ^^^^^
+
+error: unclosed HTML tag `i32`
+  --> $DIR/html-as-generics-no-suggestions.rs:53:13
+   |
+LL | /// This Vec<i32 class="test"> thing!
+   |             ^^^^
+
 error: unopened HTML tag `i32`
-  --> $DIR/html-as-generics-no-suggestions.rs:20:13
+  --> $DIR/html-as-generics-no-suggestions.rs:62:13
    |
 LL | /// This Vec</i32> thing!
    |             ^^^^^^
 
 error: unclosed HTML tag `i32`
-  --> $DIR/html-as-generics-no-suggestions.rs:25:13
+  --> $DIR/html-as-generics-no-suggestions.rs:67:13
    |
 LL | /// This 123<i32> thing!
    |             ^^^^^
 
 error: unclosed HTML tag `i32`
-  --> $DIR/html-as-generics-no-suggestions.rs:30:14
+  --> $DIR/html-as-generics-no-suggestions.rs:72:14
    |
 LL | /// This Vec:<i32> thing!
    |              ^^^^^
 
 error: unclosed HTML tag `i32`
-  --> $DIR/html-as-generics-no-suggestions.rs:35:39
+  --> $DIR/html-as-generics-no-suggestions.rs:77:39
    |
 LL | /// This [link](https://rust-lang.org)<i32> thing!
    |                                       ^^^^^
 
-error: aborting due to 5 previous errors
+error: aborting due to 10 previous errors
 
diff --git a/src/test/rustdoc-ui/suggestions/html-as-generics.fixed b/src/test/rustdoc-ui/suggestions/html-as-generics.fixed
index c0a0de24c52..07c8c9ff254 100644
--- a/src/test/rustdoc-ui/suggestions/html-as-generics.fixed
+++ b/src/test/rustdoc-ui/suggestions/html-as-generics.fixed
@@ -30,3 +30,43 @@ pub struct BareTurbofish;
 //~^ERROR unclosed HTML tag `i32`
 //~|HELP try marking as source
 pub struct Nested;
+
+/// Nested generics `Vec<Vec<u32>>`
+//~^ ERROR unclosed HTML tag `u32`
+//~|HELP try marking as source
+pub struct NestedGenerics;
+
+/// Generics with path `Vec<i32>::Iter`
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct GenericsWithPath;
+
+/// Generics with path `<Vec<i32>>::Iter`
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithPath;
+
+/// Generics with path `Vec<Vec<i32>>::Iter`
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithPath2;
+
+/// Generics with bump `<Vec<i32>>`s
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithBump;
+
+/// Generics with bump `Vec<Vec<i32>>`s
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithBump2;
+
+/// Generics with punct `<Vec<i32>>`!
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithPunct;
+
+/// Generics with punct `Vec<Vec<i32>>`!
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithPunct2;
diff --git a/src/test/rustdoc-ui/suggestions/html-as-generics.rs b/src/test/rustdoc-ui/suggestions/html-as-generics.rs
index 0b6009b0e59..cdd652f397e 100644
--- a/src/test/rustdoc-ui/suggestions/html-as-generics.rs
+++ b/src/test/rustdoc-ui/suggestions/html-as-generics.rs
@@ -30,3 +30,43 @@ pub struct BareTurbofish;
 //~^ERROR unclosed HTML tag `i32`
 //~|HELP try marking as source
 pub struct Nested;
+
+/// Nested generics Vec<Vec<u32>>
+//~^ ERROR unclosed HTML tag `u32`
+//~|HELP try marking as source
+pub struct NestedGenerics;
+
+/// Generics with path Vec<i32>::Iter
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct GenericsWithPath;
+
+/// Generics with path <Vec<i32>>::Iter
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithPath;
+
+/// Generics with path Vec<Vec<i32>>::Iter
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithPath2;
+
+/// Generics with bump <Vec<i32>>s
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithBump;
+
+/// Generics with bump Vec<Vec<i32>>s
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithBump2;
+
+/// Generics with punct <Vec<i32>>!
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithPunct;
+
+/// Generics with punct Vec<Vec<i32>>!
+//~^ ERROR unclosed HTML tag `i32`
+//~|HELP try marking as source
+pub struct NestedGenericsWithPunct2;
diff --git a/src/test/rustdoc-ui/suggestions/html-as-generics.stderr b/src/test/rustdoc-ui/suggestions/html-as-generics.stderr
index df54b71264e..211dd4210d5 100644
--- a/src/test/rustdoc-ui/suggestions/html-as-generics.stderr
+++ b/src/test/rustdoc-ui/suggestions/html-as-generics.stderr
@@ -69,5 +69,93 @@ help: try marking as source code
 LL | /// This <span>`Vec::<i32>`</span> thing!
    |                +          +
 
-error: aborting due to 6 previous errors
+error: unclosed HTML tag `u32`
+  --> $DIR/html-as-generics.rs:34:28
+   |
+LL | /// Nested generics Vec<Vec<u32>>
+   |                            ^^^^^
+   |
+help: try marking as source code
+   |
+LL | /// Nested generics `Vec<Vec<u32>>`
+   |                     +             +
+
+error: unclosed HTML tag `i32`
+  --> $DIR/html-as-generics.rs:39:27
+   |
+LL | /// Generics with path Vec<i32>::Iter
+   |                           ^^^^^
+   |
+help: try marking as source code
+   |
+LL | /// Generics with path `Vec<i32>::Iter`
+   |                        +              +
+
+error: unclosed HTML tag `i32`
+  --> $DIR/html-as-generics.rs:44:28
+   |
+LL | /// Generics with path <Vec<i32>>::Iter
+   |                            ^^^^^
+   |
+help: try marking as source code
+   |
+LL | /// Generics with path `<Vec<i32>>::Iter`
+   |                        +                +
+
+error: unclosed HTML tag `i32`
+  --> $DIR/html-as-generics.rs:49:31
+   |
+LL | /// Generics with path Vec<Vec<i32>>::Iter
+   |                               ^^^^^
+   |
+help: try marking as source code
+   |
+LL | /// Generics with path `Vec<Vec<i32>>::Iter`
+   |                        +                   +
+
+error: unclosed HTML tag `i32`
+  --> $DIR/html-as-generics.rs:54:28
+   |
+LL | /// Generics with bump <Vec<i32>>s
+   |                            ^^^^^
+   |
+help: try marking as source code
+   |
+LL | /// Generics with bump `<Vec<i32>>`s
+   |                        +          +
+
+error: unclosed HTML tag `i32`
+  --> $DIR/html-as-generics.rs:59:31
+   |
+LL | /// Generics with bump Vec<Vec<i32>>s
+   |                               ^^^^^
+   |
+help: try marking as source code
+   |
+LL | /// Generics with bump `Vec<Vec<i32>>`s
+   |                        +             +
+
+error: unclosed HTML tag `i32`
+  --> $DIR/html-as-generics.rs:64:29
+   |
+LL | /// Generics with punct <Vec<i32>>!
+   |                             ^^^^^
+   |
+help: try marking as source code
+   |
+LL | /// Generics with punct `<Vec<i32>>`!
+   |                         +          +
+
+error: unclosed HTML tag `i32`
+  --> $DIR/html-as-generics.rs:69:32
+   |
+LL | /// Generics with punct Vec<Vec<i32>>!
+   |                                ^^^^^
+   |
+help: try marking as source code
+   |
+LL | /// Generics with punct `Vec<Vec<i32>>`!
+   |                         +             +
+
+error: aborting due to 14 previous errors
 
diff --git a/src/test/rustdoc-ui/z-help.stdout b/src/test/rustdoc-ui/z-help.stdout
index 73aa0a577c4..749abe36419 100644
--- a/src/test/rustdoc-ui/z-help.stdout
+++ b/src/test/rustdoc-ui/z-help.stdout
@@ -98,6 +98,7 @@
     -Z                                     oom=val -- panic strategy for out-of-memory handling
     -Z                  osx-rpath-install-name=val -- pass `-install_name @rpath/...` to the macOS linker (default: no)
     -Z                        diagnostic-width=val -- set the current output width for diagnostic truncation
+    -Z                     packed-bundled-libs=val -- change rlib format to store native libraries as archives
     -Z                       panic-abort-tests=val -- support compiling tests with panic=abort (default: no)
     -Z                           panic-in-drop=val -- panic strategy for panics in drops
     -Z                              parse-only=val -- parse only; do not compile, assemble, or link (default: no)
diff --git a/src/test/ui/async-await/issue-101715.rs b/src/test/ui/async-await/issue-101715.rs
new file mode 100644
index 00000000000..1be5d02482e
--- /dev/null
+++ b/src/test/ui/async-await/issue-101715.rs
@@ -0,0 +1,17 @@
+// edition:2018
+
+struct S;
+
+impl S {
+    fn very_long_method_name_the_longest_method_name_in_the_whole_universe(self) {}
+}
+
+async fn foo() {
+    S.very_long_method_name_the_longest_method_name_in_the_whole_universe()
+        .await
+        //~^ error: `()` is not a future
+        //~| help: remove the `.await`
+        //~| help: the trait `Future` is not implemented for `()`
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issue-101715.stderr b/src/test/ui/async-await/issue-101715.stderr
new file mode 100644
index 00000000000..a0e8d2a8943
--- /dev/null
+++ b/src/test/ui/async-await/issue-101715.stderr
@@ -0,0 +1,16 @@
+error[E0277]: `()` is not a future
+  --> $DIR/issue-101715.rs:11:9
+   |
+LL |         .await
+   |         ^^^^^^
+   |         |
+   |         `()` is not a future
+   |         help: remove the `.await`
+   |
+   = help: the trait `Future` is not implemented for `()`
+   = note: () must be a future or must implement `IntoFuture` to be awaited
+   = note: required for `()` to implement `IntoFuture`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/issue-70594.stderr b/src/test/ui/async-await/issue-70594.stderr
index f6ff52a5fd2..d3cf57d3b14 100644
--- a/src/test/ui/async-await/issue-70594.stderr
+++ b/src/test/ui/async-await/issue-70594.stderr
@@ -22,16 +22,14 @@ error[E0277]: `()` is not a future
   --> $DIR/issue-70594.rs:4:11
    |
 LL |     [1; ().await];
-   |           ^^^^^^ `()` is not a future
+   |           ^^^^^^
+   |           |
+   |           `()` is not a future
+   |           help: remove the `.await`
    |
    = help: the trait `Future` is not implemented for `()`
    = note: () must be a future or must implement `IntoFuture` to be awaited
    = note: required for `()` to implement `IntoFuture`
-help: remove the `.await`
-   |
-LL -     [1; ().await];
-LL +     [1; ()];
-   |
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/async-await/issues/issue-62009-1.stderr b/src/test/ui/async-await/issues/issue-62009-1.stderr
index 0e323443ae8..222afb2c7b2 100644
--- a/src/test/ui/async-await/issues/issue-62009-1.stderr
+++ b/src/test/ui/async-await/issues/issue-62009-1.stderr
@@ -28,16 +28,14 @@ error[E0277]: `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]` is not a future
   --> $DIR/issue-62009-1.rs:12:15
    |
 LL |     (|_| 2333).await;
-   |               ^^^^^^ `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]` is not a future
+   |               ^^^^^^
+   |               |
+   |               `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]` is not a future
+   |               help: remove the `.await`
    |
    = help: the trait `Future` is not implemented for closure `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]`
    = note: [closure@$DIR/issue-62009-1.rs:12:6: 12:9] must be a future or must implement `IntoFuture` to be awaited
    = note: required for `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]` to implement `IntoFuture`
-help: remove the `.await`
-   |
-LL -     (|_| 2333).await;
-LL +     (|_| 2333);
-   |
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/attributes/collapse-debuginfo-invalid.rs b/src/test/ui/attributes/collapse-debuginfo-invalid.rs
new file mode 100644
index 00000000000..42d8982c118
--- /dev/null
+++ b/src/test/ui/attributes/collapse-debuginfo-invalid.rs
@@ -0,0 +1,110 @@
+#![feature(collapse_debuginfo)]
+#![feature(stmt_expr_attributes)]
+#![feature(type_alias_impl_trait)]
+#![no_std]
+
+// Test that the `#[collapse_debuginfo]` attribute can only be used on macro definitions.
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+extern crate std;
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+use std::collections::HashMap;
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+static FOO: u32 = 3;
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+const BAR: u32 = 3;
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+fn foo() {
+    let _ = #[collapse_debuginfo] || { };
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    let _ = 3;
+    let _ = #[collapse_debuginfo] 3;
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    match (3, 4) {
+        #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+        _ => (),
+    }
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+mod bar {
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+type Map = HashMap<u32, u32>;
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+enum Foo {
+    #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    Variant,
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+struct Bar {
+    #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    field: u32,
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+union Qux {
+    a: u32,
+    b: u16
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+trait Foobar {
+    #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    type Bar;
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+type AFoobar = impl Foobar;
+
+impl Foobar for Bar {
+    type Bar = u32;
+}
+
+fn constraining() -> AFoobar {
+    Bar { field: 3 }
+}
+
+#[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+impl Bar {
+    #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    const FOO: u32 = 3;
+
+    #[collapse_debuginfo]
+//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
+    fn bar(&self) {}
+}
+
+#[collapse_debuginfo]
+macro_rules! finally {
+    ($e:expr) => { $e }
+}
+
+fn main() {}
diff --git a/src/test/ui/attributes/collapse-debuginfo-invalid.stderr b/src/test/ui/attributes/collapse-debuginfo-invalid.stderr
new file mode 100644
index 00000000000..01c47609108
--- /dev/null
+++ b/src/test/ui/attributes/collapse-debuginfo-invalid.stderr
@@ -0,0 +1,222 @@
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:8:1
+   |
+LL | #[collapse_debuginfo]
+   | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | extern crate std;
+   | ----------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:12:1
+   |
+LL | #[collapse_debuginfo]
+   | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | use std::collections::HashMap;
+   | ------------------------------ not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:16:1
+   |
+LL | #[collapse_debuginfo]
+   | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | static FOO: u32 = 3;
+   | -------------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:20:1
+   |
+LL | #[collapse_debuginfo]
+   | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | const BAR: u32 = 3;
+   | ------------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:24:1
+   |
+LL |   #[collapse_debuginfo]
+   |   ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / fn foo() {
+LL | |     let _ = #[collapse_debuginfo] || { };
+LL | |
+LL | |     #[collapse_debuginfo]
+...  |
+LL | |     }
+LL | | }
+   | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:27:13
+   |
+LL |     let _ = #[collapse_debuginfo] || { };
+   |             ^^^^^^^^^^^^^^^^^^^^^ ------ not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:29:5
+   |
+LL |     #[collapse_debuginfo]
+   |     ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL |     let _ = 3;
+   |     ---------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:32:13
+   |
+LL |     let _ = #[collapse_debuginfo] 3;
+   |             ^^^^^^^^^^^^^^^^^^^^^ - not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:35:9
+   |
+LL |         #[collapse_debuginfo]
+   |         ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL |         _ => (),
+   |         ------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:41:1
+   |
+LL |   #[collapse_debuginfo]
+   |   ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / mod bar {
+LL | | }
+   | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:46:1
+   |
+LL | #[collapse_debuginfo]
+   | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | type Map = HashMap<u32, u32>;
+   | ----------------------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:50:1
+   |
+LL |   #[collapse_debuginfo]
+   |   ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / enum Foo {
+LL | |     #[collapse_debuginfo]
+LL | |
+LL | |     Variant,
+LL | | }
+   | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:53:5
+   |
+LL |     #[collapse_debuginfo]
+   |     ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL |     Variant,
+   |     ------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:58:1
+   |
+LL |   #[collapse_debuginfo]
+   |   ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / struct Bar {
+LL | |     #[collapse_debuginfo]
+LL | |
+LL | |     field: u32,
+LL | | }
+   | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:61:5
+   |
+LL |     #[collapse_debuginfo]
+   |     ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL |     field: u32,
+   |     ---------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:66:1
+   |
+LL |   #[collapse_debuginfo]
+   |   ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / union Qux {
+LL | |     a: u32,
+LL | |     b: u16
+LL | | }
+   | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:73:1
+   |
+LL |   #[collapse_debuginfo]
+   |   ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / trait Foobar {
+LL | |     #[collapse_debuginfo]
+LL | |
+LL | |     type Bar;
+LL | | }
+   | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:81:1
+   |
+LL | #[collapse_debuginfo]
+   | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | type AFoobar = impl Foobar;
+   | --------------------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:93:1
+   |
+LL |   #[collapse_debuginfo]
+   |   ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | / impl Bar {
+LL | |     #[collapse_debuginfo]
+LL | |
+LL | |     const FOO: u32 = 3;
+...  |
+LL | |     fn bar(&self) {}
+LL | | }
+   | |_- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:76:5
+   |
+LL |     #[collapse_debuginfo]
+   |     ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL |     type Bar;
+   |     --------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:96:5
+   |
+LL |     #[collapse_debuginfo]
+   |     ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL |     const FOO: u32 = 3;
+   |     ------------------- not a macro definition
+
+error: `collapse_debuginfo` attribute should be applied to macro definitions
+  --> $DIR/collapse-debuginfo-invalid.rs:100:5
+   |
+LL |     #[collapse_debuginfo]
+   |     ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL |     fn bar(&self) {}
+   |     ---------------- not a macro definition
+
+error: aborting due to 22 previous errors
+
diff --git a/src/test/ui/feature-gates/feature-gate-collapse_debuginfo.rs b/src/test/ui/feature-gates/feature-gate-collapse_debuginfo.rs
new file mode 100644
index 00000000000..f73bf579f6d
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-collapse_debuginfo.rs
@@ -0,0 +1,7 @@
+#[collapse_debuginfo]
+//~^ ERROR the `#[collapse_debuginfo]` attribute is an experimental feature
+macro_rules! foo {
+    ($e:expr) => { $e }
+}
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-collapse_debuginfo.stderr b/src/test/ui/feature-gates/feature-gate-collapse_debuginfo.stderr
new file mode 100644
index 00000000000..2cbde893af9
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-collapse_debuginfo.stderr
@@ -0,0 +1,12 @@
+error[E0658]: the `#[collapse_debuginfo]` attribute is an experimental feature
+  --> $DIR/feature-gate-collapse_debuginfo.rs:1:1
+   |
+LL | #[collapse_debuginfo]
+   | ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #100758 <https://github.com/rust-lang/rust/issues/100758> for more information
+   = help: add `#![feature(collapse_debuginfo)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/proc-macro/dollar-crate-issue-101211.rs b/src/test/ui/proc-macro/dollar-crate-issue-101211.rs
new file mode 100644
index 00000000000..fc1acfd32d2
--- /dev/null
+++ b/src/test/ui/proc-macro/dollar-crate-issue-101211.rs
@@ -0,0 +1,29 @@
+// check-pass
+// edition:2021
+// aux-build:test-macros.rs
+
+#![no_std] // Don't load unnecessary hygiene information from std
+extern crate std;
+
+#[macro_use]
+extern crate test_macros;
+
+macro_rules! foo {
+    ($($path:ident)::*) => (
+        test_macros::recollect!(
+            $($path)::*
+        )
+    )
+}
+
+macro_rules! baz {
+    () => (
+        foo!($crate::BAR)
+    )
+}
+
+pub const BAR: u32 = 19;
+
+fn main(){
+    std::println!("{}", baz!());
+}
diff --git a/src/test/ui/typeof/issue-100183.rs b/src/test/ui/typeof/issue-100183.rs
new file mode 100644
index 00000000000..13e9493eaa5
--- /dev/null
+++ b/src/test/ui/typeof/issue-100183.rs
@@ -0,0 +1,6 @@
+struct Struct {
+    y: (typeof("hey"),),
+    //~^ ERROR `typeof` is a reserved keyword but unimplemented
+}
+
+fn main() {}
diff --git a/src/test/ui/typeof/issue-100183.stderr b/src/test/ui/typeof/issue-100183.stderr
new file mode 100644
index 00000000000..01d3079b246
--- /dev/null
+++ b/src/test/ui/typeof/issue-100183.stderr
@@ -0,0 +1,14 @@
+error[E0516]: `typeof` is a reserved keyword but unimplemented
+  --> $DIR/issue-100183.rs:2:9
+   |
+LL |     y: (typeof("hey"),),
+   |         ^^^^^^^^^^^^^ reserved keyword
+   |
+help: consider replacing `typeof(...)` with an actual type
+   |
+LL |     y: (&'static str,),
+   |         ~~~~~~~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0516`.
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
index 93874b103b4..d37f44d4a17 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
@@ -8,11 +8,10 @@ use rustc_arena::DroplessArena;
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
-use rustc_hir::{Arm, Expr, ExprKind, HirId, HirIdMap, HirIdSet, Pat, PatKind, RangeEnd};
+use rustc_hir::{Arm, Expr, ExprKind, HirId, HirIdMap, HirIdMapEntry, HirIdSet, Pat, PatKind, RangeEnd};
 use rustc_lint::LateContext;
 use rustc_middle::ty;
 use rustc_span::Symbol;
-use std::collections::hash_map::Entry;
 
 use super::MATCH_SAME_ARMS;
 
@@ -71,9 +70,9 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {
                 if let Some(a_id) = path_to_local(a);
                 if let Some(b_id) = path_to_local(b);
                 let entry = match local_map.entry(a_id) {
-                    Entry::Vacant(entry) => entry,
+                    HirIdMapEntry::Vacant(entry) => entry,
                     // check if using the same bindings as before
-                    Entry::Occupied(entry) => return *entry.get() == b_id,
+                    HirIdMapEntry::Occupied(entry) => return *entry.get() == b_id,
                 };
                 // the names technically don't have to match; this makes the lint more conservative
                 if cx.tcx.hir().name(a_id) == cx.tcx.hir().name(b_id);
diff --git a/src/tools/miri b/src/tools/miri
-Subproject ef3f649e49607a1fad64eb0a5139110df3efa2a
+Subproject beed5eddb0f73f6721681560c73a51e3f15b868
diff --git a/triagebot.toml b/triagebot.toml
index ceda7ef5f16..4b2dcc246e4 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -11,6 +11,7 @@ allow-unauthenticated = [
     "S-*",
     "T-*",
     "WG-*",
+    "const-hack",
     "needs-fcp",
     "relnotes",
     "requires-nightly",