about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock4
-rw-r--r--compiler/rustc_builtin_macros/src/proc_macro_harness.rs83
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs81
-rw-r--r--compiler/rustc_expand/src/base.rs94
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs6
-rw-r--r--compiler/rustc_interface/src/passes.rs8
-rw-r--r--compiler/rustc_interface/src/tests.rs1
-rw-r--r--compiler/rustc_metadata/src/creader.rs8
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs30
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs5
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs13
-rw-r--r--compiler/rustc_middle/src/ich/impls_syntax.rs1
-rw-r--r--compiler/rustc_middle/src/lint.rs14
-rw-r--r--compiler/rustc_middle/src/middle/cstore.rs23
-rw-r--r--compiler/rustc_middle/src/query/mod.rs3
-rw-r--r--compiler/rustc_middle/src/ty/context.rs9
-rw-r--r--compiler/rustc_mir/src/interpret/memory.rs1
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs2
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--library/alloc/src/sync.rs8
-rw-r--r--library/core/src/iter/adapters/fuse.rs254
-rw-r--r--library/core/src/lib.rs10
-rw-r--r--library/core/src/macros/mod.rs20
-rw-r--r--library/core/src/slice/rotate.rs56
-rw-r--r--library/std/src/lib.rs4
-rw-r--r--library/std/src/macros.rs3
-rw-r--r--library/std/src/os/wasi/fs.rs2
-rw-r--r--library/std/src/os/wasi/io.rs2
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile2
-rw-r--r--src/librustdoc/doctest.rs20
-rw-r--r--src/librustdoc/html/markdown.rs51
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css2
-rw-r--r--src/librustdoc/html/static/css/themes/ayu.css2
-rw-r--r--src/librustdoc/lib.rs4
-rw-r--r--src/librustdoc/markdown.rs4
-rw-r--r--src/test/debuginfo/function-names.rs30
-rw-r--r--src/test/rustdoc-gui/ayu-code-tag-colors.goml13
-rw-r--r--src/test/rustdoc-gui/code-blocks-overflow.goml8
-rw-r--r--src/test/rustdoc-gui/src/lib2/lib.rs14
-rw-r--r--src/test/rustdoc-gui/src/test_docs/lib.rs1
-rw-r--r--src/test/ui/crate-loading/auxiliary/proc-macro.rs12
-rw-r--r--src/test/ui/crate-loading/cross-compiled-proc-macro.rs8
-rw-r--r--src/test/ui/deriving/deriving-with-helper.rs36
-rw-r--r--src/test/ui/lint/future-incompat-test.rs10
-rw-r--r--src/test/ui/lint/future-incompat-test.stderr9
-rw-r--r--src/test/ui/macros/assert-matches-macro-msg.rs2
-rw-r--r--src/test/ui/matches2021.rs2
-rw-r--r--src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stderr10
-rw-r--r--src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr2
-rw-r--r--src/test/ui/resolve/resolve-hint-macro.rs4
-rw-r--r--src/test/ui/resolve/resolve-hint-macro.stderr10
-rw-r--r--src/tools/compiletest/src/json.rs5
52 files changed, 586 insertions, 422 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 6885ac65ca9..0aa132fe29a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -646,9 +646,9 @@ dependencies = [
 
 [[package]]
 name = "compiler_builtins"
-version = "0.1.46"
+version = "0.1.47"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d69484e04eab372f5f345920e3a8c7a06e7dcbb75c0944eccdc3e3160aeee3c7"
+checksum = "fd4ed89e0a5c3e50b15c0045fbe1ff8567b703bc07544faf935ddff0aaa7b65f"
 dependencies = [
  "cc",
  "rustc-std-workspace-core",
diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
index 71bbae1161b..a8c61d53346 100644
--- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
+++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
@@ -5,7 +5,7 @@ use rustc_ast::ptr::P;
 use rustc_ast::visit::{self, Visitor};
 use rustc_ast::{self as ast, NodeId};
 use rustc_ast_pretty::pprust;
-use rustc_expand::base::{ExtCtxt, ResolverExpand};
+use rustc_expand::base::{parse_macro_name_and_helper_attrs, ExtCtxt, ResolverExpand};
 use rustc_expand::expand::{AstFragment, ExpansionConfig};
 use rustc_session::Session;
 use rustc_span::hygiene::AstPass;
@@ -109,86 +109,17 @@ impl<'a> CollectProcMacros<'a> {
     }
 
     fn collect_custom_derive(&mut self, item: &'a ast::Item, attr: &'a ast::Attribute) {
-        // Once we've located the `#[proc_macro_derive]` attribute, verify
-        // that it's of the form `#[proc_macro_derive(Foo)]` or
-        // `#[proc_macro_derive(Foo, attributes(A, ..))]`
-        let list = match attr.meta_item_list() {
-            Some(list) => list,
-            None => return,
-        };
-        if list.len() != 1 && list.len() != 2 {
-            self.handler.span_err(attr.span, "attribute must have either one or two arguments");
-            return;
-        }
-        let trait_attr = match list[0].meta_item() {
-            Some(meta_item) => meta_item,
-            _ => {
-                self.handler.span_err(list[0].span(), "not a meta item");
-                return;
-            }
-        };
-        let trait_ident = match trait_attr.ident() {
-            Some(trait_ident) if trait_attr.is_word() => trait_ident,
-            _ => {
-                self.handler.span_err(trait_attr.span, "must only be one word");
-                return;
-            }
-        };
-
-        if !trait_ident.name.can_be_raw() {
-            self.handler.span_err(
-                trait_attr.span,
-                &format!("`{}` cannot be a name of derive macro", trait_ident),
-            );
-        }
-
-        let attributes_attr = list.get(1);
-        let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr {
-            if !attr.has_name(sym::attributes) {
-                self.handler.span_err(attr.span(), "second argument must be `attributes`")
-            }
-            attr.meta_item_list()
-                .unwrap_or_else(|| {
-                    self.handler
-                        .span_err(attr.span(), "attribute must be of form: `attributes(foo, bar)`");
-                    &[]
-                })
-                .iter()
-                .filter_map(|attr| {
-                    let attr = match attr.meta_item() {
-                        Some(meta_item) => meta_item,
-                        _ => {
-                            self.handler.span_err(attr.span(), "not a meta item");
-                            return None;
-                        }
-                    };
-
-                    let ident = match attr.ident() {
-                        Some(ident) if attr.is_word() => ident,
-                        _ => {
-                            self.handler.span_err(attr.span, "must only be one word");
-                            return None;
-                        }
-                    };
-                    if !ident.name.can_be_raw() {
-                        self.handler.span_err(
-                            attr.span,
-                            &format!("`{}` cannot be a name of derive helper attribute", ident),
-                        );
-                    }
-
-                    Some(ident.name)
-                })
-                .collect()
-        } else {
-            Vec::new()
-        };
+        let (trait_name, proc_attrs) =
+            match parse_macro_name_and_helper_attrs(self.handler, attr, "derive") {
+                Some(name_and_attrs) => name_and_attrs,
+                None => return,
+            };
 
         if self.in_root && item.vis.kind.is_pub() {
             self.macros.push(ProcMacro::Derive(ProcMacroDerive {
                 id: item.id,
                 span: item.span,
-                trait_name: trait_ident.name,
+                trait_name,
                 function_name: item.ident,
                 attrs: proc_attrs,
             }));
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index b3c14d9072c..25268d9a555 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -12,12 +12,15 @@
 // * `"` is treated as the start of a string.
 
 use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData};
+use rustc_middle::ich::NodeIdHashingMode;
+use rustc_middle::ty::layout::IntegerExt;
 use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
 use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
-use rustc_target::abi::{TagEncoding, Variants};
+use rustc_target::abi::{Integer, TagEncoding, Variants};
 
 use std::fmt::Write;
 
@@ -47,7 +50,7 @@ pub fn push_debuginfo_type_name<'tcx>(
 ) {
     // When targeting MSVC, emit C++ style type names for compatibility with
     // .natvis visualizers (and perhaps other existing native debuggers?)
-    let cpp_like_names = tcx.sess.target.is_like_msvc;
+    let cpp_like_names = cpp_like_names(tcx);
 
     match *t.kind() {
         ty::Bool => output.push_str("bool"),
@@ -424,8 +427,6 @@ fn push_unqualified_item_name(
     disambiguated_data: DisambiguatedDefPathData,
     output: &mut String,
 ) {
-    let cpp_like_names = tcx.sess.target.is_like_msvc;
-
     match disambiguated_data.data {
         DefPathData::CrateRoot => {
             output.push_str(&tcx.crate_name(def_id.krate).as_str());
@@ -433,7 +434,7 @@ fn push_unqualified_item_name(
         DefPathData::ClosureExpr if tcx.generator_kind(def_id).is_some() => {
             // Generators look like closures, but we want to treat them differently
             // in the debug info.
-            if cpp_like_names {
+            if cpp_like_names(tcx) {
                 write!(output, "generator${}", disambiguated_data.disambiguator).unwrap();
             } else {
                 write!(output, "{{generator#{}}}", disambiguated_data.disambiguator).unwrap();
@@ -444,7 +445,7 @@ fn push_unqualified_item_name(
                 output.push_str(&name.as_str());
             }
             DefPathDataName::Anon { namespace } => {
-                if cpp_like_names {
+                if cpp_like_names(tcx) {
                     write!(output, "{}${}", namespace, disambiguated_data.disambiguator).unwrap();
                 } else {
                     write!(output, "{{{}#{}}}", namespace, disambiguated_data.disambiguator)
@@ -478,19 +479,14 @@ fn push_generic_params_internal<'tcx>(
         match type_parameter {
             GenericArgKind::Type(type_parameter) => {
                 push_debuginfo_type_name(tcx, type_parameter, true, output, visited);
-                output.push_str(", ");
-            }
-            GenericArgKind::Const(const_parameter) => match const_parameter.val {
-                ty::ConstKind::Param(param) => write!(output, "{}, ", param.name).unwrap(),
-                _ => write!(
-                    output,
-                    "0x{:x}, ",
-                    const_parameter.eval_bits(tcx, ty::ParamEnv::reveal_all(), const_parameter.ty)
-                )
-                .unwrap(),
-            },
+            }
+            GenericArgKind::Const(ct) => {
+                push_const_param(tcx, ct, output);
+            }
             other => bug!("Unexpected non-erasable generic: {:?}", other),
         }
+
+        output.push_str(", ");
     }
 
     output.pop();
@@ -499,6 +495,51 @@ fn push_generic_params_internal<'tcx>(
     push_close_angle_bracket(tcx, output);
 }
 
+fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: &'tcx ty::Const<'tcx>, output: &mut String) {
+    match ct.val {
+        ty::ConstKind::Param(param) => {
+            write!(output, "{}", param.name)
+        }
+        _ => match ct.ty.kind() {
+            ty::Int(ity) => {
+                let bits = ct.eval_bits(tcx, ty::ParamEnv::reveal_all(), ct.ty);
+                let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
+                write!(output, "{}", val)
+            }
+            ty::Uint(_) => {
+                let val = ct.eval_bits(tcx, ty::ParamEnv::reveal_all(), ct.ty);
+                write!(output, "{}", val)
+            }
+            ty::Bool => {
+                let val = ct.try_eval_bool(tcx, ty::ParamEnv::reveal_all()).unwrap();
+                write!(output, "{}", val)
+            }
+            _ => {
+                // If we cannot evaluate the constant to a known type, we fall back
+                // to emitting a stable hash value of the constant. This isn't very pretty
+                // but we get a deterministic, virtually unique value for the constant.
+                let hcx = &mut tcx.create_stable_hashing_context();
+                let mut hasher = StableHasher::new();
+                hcx.while_hashing_spans(false, |hcx| {
+                    hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
+                        ct.val.hash_stable(hcx, &mut hasher);
+                    });
+                });
+                // Let's only emit 64 bits of the hash value. That should be plenty for
+                // avoiding collisions and will make the emitted type names shorter.
+                let hash: u64 = hasher.finish();
+
+                if cpp_like_names(tcx) {
+                    write!(output, "CONST${:x}", hash)
+                } else {
+                    write!(output, "{{CONST#{:x}}}", hash)
+                }
+            }
+        },
+    }
+    .unwrap();
+}
+
 pub fn push_generic_params<'tcx>(tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>, output: &mut String) {
     let mut visited = FxHashSet::default();
     push_generic_params_internal(tcx, substs, output, &mut visited);
@@ -507,9 +548,13 @@ pub fn push_generic_params<'tcx>(tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>, out
 fn push_close_angle_bracket<'tcx>(tcx: TyCtxt<'tcx>, output: &mut String) {
     // MSVC debugger always treats `>>` as a shift, even when parsing templates,
     // so add a space to avoid confusion.
-    if tcx.sess.target.is_like_msvc && output.ends_with('>') {
+    if cpp_like_names(tcx) && output.ends_with('>') {
         output.push(' ')
     };
 
     output.push('>');
 }
+
+fn cpp_like_names(tcx: TyCtxt<'_>) -> bool {
+    tcx.sess.target.is_like_msvc
+}
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index b3e52502b07..0183add4957 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -745,9 +745,17 @@ impl SyntaxExtension {
             }
         }
 
-        let builtin_name = sess
+        let (builtin_name, helper_attrs) = sess
             .find_by_name(attrs, sym::rustc_builtin_macro)
-            .map(|a| a.value_str().unwrap_or(name));
+            .map(|attr| {
+                // Override `helper_attrs` passed above if it's a built-in macro,
+                // marking `proc_macro_derive` macros as built-in is not a realistic use case.
+                parse_macro_name_and_helper_attrs(sess.diagnostic(), attr, "built-in").map_or_else(
+                    || (Some(name), Vec::new()),
+                    |(name, helper_attrs)| (Some(name), helper_attrs),
+                )
+            })
+            .unwrap_or_else(|| (None, helper_attrs));
         let (stability, const_stability) = attr::find_stability(&sess, attrs, span);
         if let Some((_, sp)) = const_stability {
             sess.parse_sess
@@ -1213,6 +1221,88 @@ pub fn get_exprs_from_tts(
     Some(es)
 }
 
+pub fn parse_macro_name_and_helper_attrs(
+    diag: &rustc_errors::Handler,
+    attr: &Attribute,
+    descr: &str,
+) -> Option<(Symbol, Vec<Symbol>)> {
+    // Once we've located the `#[proc_macro_derive]` attribute, verify
+    // that it's of the form `#[proc_macro_derive(Foo)]` or
+    // `#[proc_macro_derive(Foo, attributes(A, ..))]`
+    let list = match attr.meta_item_list() {
+        Some(list) => list,
+        None => return None,
+    };
+    if list.len() != 1 && list.len() != 2 {
+        diag.span_err(attr.span, "attribute must have either one or two arguments");
+        return None;
+    }
+    let trait_attr = match list[0].meta_item() {
+        Some(meta_item) => meta_item,
+        _ => {
+            diag.span_err(list[0].span(), "not a meta item");
+            return None;
+        }
+    };
+    let trait_ident = match trait_attr.ident() {
+        Some(trait_ident) if trait_attr.is_word() => trait_ident,
+        _ => {
+            diag.span_err(trait_attr.span, "must only be one word");
+            return None;
+        }
+    };
+
+    if !trait_ident.name.can_be_raw() {
+        diag.span_err(
+            trait_attr.span,
+            &format!("`{}` cannot be a name of {} macro", trait_ident, descr),
+        );
+    }
+
+    let attributes_attr = list.get(1);
+    let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr {
+        if !attr.has_name(sym::attributes) {
+            diag.span_err(attr.span(), "second argument must be `attributes`")
+        }
+        attr.meta_item_list()
+            .unwrap_or_else(|| {
+                diag.span_err(attr.span(), "attribute must be of form: `attributes(foo, bar)`");
+                &[]
+            })
+            .iter()
+            .filter_map(|attr| {
+                let attr = match attr.meta_item() {
+                    Some(meta_item) => meta_item,
+                    _ => {
+                        diag.span_err(attr.span(), "not a meta item");
+                        return None;
+                    }
+                };
+
+                let ident = match attr.ident() {
+                    Some(ident) if attr.is_word() => ident,
+                    _ => {
+                        diag.span_err(attr.span, "must only be one word");
+                        return None;
+                    }
+                };
+                if !ident.name.can_be_raw() {
+                    diag.span_err(
+                        attr.span,
+                        &format!("`{}` cannot be a name of derive helper attribute", ident),
+                    );
+                }
+
+                Some(ident.name)
+            })
+            .collect()
+    } else {
+        Vec::new()
+    };
+
+    Some((trait_ident.name, proc_attrs))
+}
+
 /// This nonterminal looks like some specific enums from
 /// `proc-macro-hack` and `procedural-masquerade` crates.
 /// We need to maintain some special pretty-printing behavior for them due to incorrect
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 77d8f0f920c..b1c725ecd85 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -448,7 +448,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     // Internal attributes, Macro related:
     // ==========================================================================
 
-    rustc_attr!(rustc_builtin_macro, AssumedUsed, template!(Word, NameValueStr: "name"), IMPL_DETAIL),
+    rustc_attr!(
+        rustc_builtin_macro, AssumedUsed,
+        template!(Word, List: "name, /*opt*/ attributes(name1, name2, ...)"),
+        IMPL_DETAIL,
+    ),
     rustc_attr!(rustc_proc_macro_decls, Normal, template!(Word), INTERNAL_UNSTABLE),
     rustc_attr!(
         rustc_macro_transparency, AssumedUsed,
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index e568b5ca501..958a4ab6802 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -18,7 +18,7 @@ use rustc_metadata::creader::CStore;
 use rustc_middle::arena::Arena;
 use rustc_middle::dep_graph::DepGraph;
 use rustc_middle::middle;
-use rustc_middle::middle::cstore::{CrateStore, MetadataLoader, MetadataLoaderDyn};
+use rustc_middle::middle::cstore::{MetadataLoader, MetadataLoaderDyn};
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{self, GlobalCtxt, ResolverOutputs, TyCtxt};
 use rustc_mir as mir;
@@ -860,11 +860,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
                     tcx.ensure().proc_macro_decls_static(())
                 });
 
-                let cstore = tcx
-                    .cstore_as_any()
-                    .downcast_ref::<CStore>()
-                    .expect("`tcx.cstore` is not a `CStore`");
-                cstore.report_unused_deps(tcx);
+                CStore::from_tcx(tcx).report_unused_deps(tcx);
             },
             {
                 par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| {
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index a053253ec16..5a362a37f2b 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -633,6 +633,7 @@ fn test_debugging_options_tracking_hash() {
     untracked!(dump_mir_graphviz, true);
     untracked!(emit_future_incompat_report, true);
     untracked!(emit_stack_sizes, true);
+    untracked!(future_incompat_test, true);
     untracked!(hir_stats, true);
     untracked!(identify_regions, true);
     untracked!(incremental_ignore_spans, true);
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 250af3c6e89..70b3efa1d16 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -130,7 +130,7 @@ impl<'a> std::fmt::Debug for CrateDump<'a> {
 }
 
 impl CStore {
-    crate fn from_tcx(tcx: TyCtxt<'_>) -> &CStore {
+    pub fn from_tcx(tcx: TyCtxt<'_>) -> &CStore {
         tcx.cstore_as_any().downcast_ref::<CStore>().expect("`tcx.cstore` is not a `CStore`")
     }
 
@@ -599,7 +599,11 @@ impl<'a> CrateLoader<'a> {
         // don't want to match a host crate against an equivalent target one
         // already loaded.
         let root = library.metadata.get_root();
-        Ok(Some(if locator.triple == self.sess.opts.target_triple {
+        // FIXME: why is this condition necessary? It was adding in #33625 but I
+        // don't know why and the original author doesn't remember ...
+        let can_reuse_cratenum =
+            locator.triple == self.sess.opts.target_triple || locator.is_proc_macro == Some(true);
+        Ok(Some(if can_reuse_cratenum {
             let mut result = LoadResult::Loaded(library);
             self.cstore.iter_crate_data(|cnum, data| {
                 if data.name() == root.name() && root.hash() == data.hash() {
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index d96034c951c..ce8dfeae076 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -5,7 +5,6 @@ use crate::rmeta::encoder;
 
 use rustc_ast as ast;
 use rustc_data_structures::stable_map::FxHashMap;
-use rustc_data_structures::svh::Svh;
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE};
@@ -369,6 +368,7 @@ pub fn provide(providers: &mut Providers) {
             tcx.arena
                 .alloc_slice(&CStore::from_tcx(tcx).crate_dependencies_in_postorder(LOCAL_CRATE))
         },
+        crates: |tcx, ()| tcx.arena.alloc_slice(&CStore::from_tcx(tcx).crates_untracked()),
 
         ..*providers
     };
@@ -451,6 +451,16 @@ impl CStore {
         self.get_crate_data(def_id.krate).get_span(def_id.index, sess)
     }
 
+    pub fn def_kind(&self, def: DefId) -> DefKind {
+        self.get_crate_data(def.krate).def_kind(def.index)
+    }
+
+    pub fn crates_untracked(&self) -> Vec<CrateNum> {
+        let mut result = vec![];
+        self.iter_crate_data(|cnum, _| result.push(cnum));
+        result
+    }
+
     pub fn item_generics_num_lifetimes(&self, def_id: DefId, sess: &Session) -> usize {
         self.get_crate_data(def_id.krate).get_generics(def_id.index, sess).own_counts().lifetimes
     }
@@ -485,18 +495,14 @@ impl CrateStore for CStore {
         self
     }
 
-    fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol {
+    fn crate_name(&self, cnum: CrateNum) -> Symbol {
         self.get_crate_data(cnum).root.name
     }
 
-    fn stable_crate_id_untracked(&self, cnum: CrateNum) -> StableCrateId {
+    fn stable_crate_id(&self, cnum: CrateNum) -> StableCrateId {
         self.get_crate_data(cnum).root.stable_crate_id
     }
 
-    fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh {
-        self.get_crate_data(cnum).root.hash
-    }
-
     /// Returns the `DefKey` for a given `DefId`. This indicates the
     /// parent `DefId` as well as some idea of what kind of data the
     /// `DefId` refers to.
@@ -504,10 +510,6 @@ impl CrateStore for CStore {
         self.get_crate_data(def.krate).def_key(def.index)
     }
 
-    fn def_kind(&self, def: DefId) -> DefKind {
-        self.get_crate_data(def.krate).def_kind(def.index)
-    }
-
     fn def_path(&self, def: DefId) -> DefPath {
         self.get_crate_data(def.krate).def_path(def.index)
     }
@@ -526,12 +528,6 @@ impl CrateStore for CStore {
         self.get_crate_data(cnum).def_path_hash_to_def_id(cnum, index_guess, hash)
     }
 
-    fn crates_untracked(&self) -> Vec<CrateNum> {
-        let mut result = vec![];
-        self.iter_crate_data(|cnum, _| result.push(cnum));
-        result
-    }
-
     fn encode_metadata(&self, tcx: TyCtxt<'_>) -> EncodedMetadata {
         encoder::encode_metadata(tcx)
     }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 602e1fd822c..5c7d84e2bc9 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1061,10 +1061,7 @@ impl EncodeContext<'a, 'tcx> {
             Lazy::empty()
         };
 
-        let data = ModData {
-            reexports,
-            expansion: tcx.resolutions(()).definitions.expansion_that_defined(local_def_id),
-        };
+        let data = ModData { reexports, expansion: tcx.expn_that_defined(local_def_id) };
 
         record!(self.tables.kind[def_id] <- EntryKind::Mod(self.lazy(data)));
         if self.is_proc_macro {
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 5c32c0fdb6c..ae53f1ac3bb 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -1,7 +1,6 @@
 use self::collector::NodeCollector;
 
 use crate::hir::{AttributeMap, IndexedHir};
-use crate::middle::cstore::CrateStore;
 use crate::ty::TyCtxt;
 use rustc_ast as ast;
 use rustc_data_structures::fingerprint::Fingerprint;
@@ -991,7 +990,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
         },
     );
 
-    let upstream_crates = upstream_crates(&*tcx.untracked_resolutions.cstore);
+    let upstream_crates = upstream_crates(tcx);
 
     // We hash the final, remapped names of all local source files so we
     // don't have to include the path prefix remapping commandline args.
@@ -1021,13 +1020,13 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
     Svh::new(crate_hash.to_smaller_hash())
 }
 
-fn upstream_crates(cstore: &dyn CrateStore) -> Vec<(StableCrateId, Svh)> {
-    let mut upstream_crates: Vec<_> = cstore
-        .crates_untracked()
+fn upstream_crates(tcx: TyCtxt<'_>) -> Vec<(StableCrateId, Svh)> {
+    let mut upstream_crates: Vec<_> = tcx
+        .crates(())
         .iter()
         .map(|&cnum| {
-            let stable_crate_id = cstore.stable_crate_id_untracked(cnum);
-            let hash = cstore.crate_hash_untracked(cnum);
+            let stable_crate_id = tcx.resolutions(()).cstore.stable_crate_id(cnum);
+            let hash = tcx.crate_hash(cnum);
             (stable_crate_id, hash)
         })
         .collect();
diff --git a/compiler/rustc_middle/src/ich/impls_syntax.rs b/compiler/rustc_middle/src/ich/impls_syntax.rs
index 2d8f661ef59..1c66f831b5f 100644
--- a/compiler/rustc_middle/src/ich/impls_syntax.rs
+++ b/compiler/rustc_middle/src/ich/impls_syntax.rs
@@ -6,6 +6,7 @@ use crate::ich::StableHashingContext;
 use rustc_ast as ast;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_span::{BytePos, NormalizedPos, SourceFile};
+use std::assert::assert_matches;
 
 use smallvec::SmallVec;
 
diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs
index 484e30027e5..848e60fe134 100644
--- a/compiler/rustc_middle/src/lint.rs
+++ b/compiler/rustc_middle/src/lint.rs
@@ -8,7 +8,7 @@ use rustc_hir::HirId;
 use rustc_index::vec::IndexVec;
 use rustc_session::lint::{
     builtin::{self, FORBIDDEN_LINT_GROUPS},
-    FutureIncompatibilityReason, FutureIncompatibleInfo, Level, Lint, LintId,
+    FutureIncompatibilityReason, Level, Lint, LintId,
 };
 use rustc_session::{DiagnosticMessageId, Session};
 use rustc_span::hygiene::MacroKind;
@@ -223,12 +223,12 @@ pub fn struct_lint_level<'s, 'd>(
         let lint_id = LintId::of(lint);
         let future_incompatible = lint.future_incompatible;
 
-        let has_future_breakage = matches!(
-            future_incompatible,
-            Some(FutureIncompatibleInfo {
-                reason: FutureIncompatibilityReason::FutureReleaseErrorReportNow,
-                ..
-            })
+        let has_future_breakage = future_incompatible.map_or(
+            // Default allow lints trigger too often for testing.
+            sess.opts.debugging_opts.future_incompat_test && lint.default_level != Level::Allow,
+            |incompat| {
+                matches!(incompat.reason, FutureIncompatibilityReason::FutureReleaseErrorReportNow)
+            },
         );
 
         let mut err = match (level, span) {
diff --git a/compiler/rustc_middle/src/middle/cstore.rs b/compiler/rustc_middle/src/middle/cstore.rs
index fcd4988635b..7efe8e061e8 100644
--- a/compiler/rustc_middle/src/middle/cstore.rs
+++ b/compiler/rustc_middle/src/middle/cstore.rs
@@ -5,9 +5,7 @@
 use crate::ty::TyCtxt;
 
 use rustc_ast as ast;
-use rustc_data_structures::svh::Svh;
 use rustc_data_structures::sync::{self, MetadataRef};
-use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
 use rustc_macros::HashStable;
@@ -190,11 +188,19 @@ pub type MetadataLoaderDyn = dyn MetadataLoader + Sync;
 pub trait CrateStore: std::fmt::Debug {
     fn as_any(&self) -> &dyn Any;
 
-    // resolve
+    // Foreign definitions.
+    // This information is safe to access, since it's hashed as part of the DefPathHash, which incr.
+    // comp. uses to identify a DefId.
     fn def_key(&self, def: DefId) -> DefKey;
-    fn def_kind(&self, def: DefId) -> DefKind;
     fn def_path(&self, def: DefId) -> DefPath;
     fn def_path_hash(&self, def: DefId) -> DefPathHash;
+
+    // This information is safe to access, since it's hashed as part of the StableCrateId, which
+    // incr.  comp. uses to identify a CrateNum.
+    fn crate_name(&self, cnum: CrateNum) -> Symbol;
+    fn stable_crate_id(&self, cnum: CrateNum) -> StableCrateId;
+
+    /// Fetch a DefId from a DefPathHash for a foreign crate.
     fn def_path_hash_to_def_id(
         &self,
         cnum: CrateNum,
@@ -202,15 +208,6 @@ pub trait CrateStore: std::fmt::Debug {
         hash: DefPathHash,
     ) -> Option<DefId>;
 
-    // "queries" used in resolve that aren't tracked for incremental compilation
-    fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol;
-    fn stable_crate_id_untracked(&self, cnum: CrateNum) -> StableCrateId;
-    fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh;
-
-    // This is basically a 1-based range of ints, which is a little
-    // silly - I may fix that.
-    fn crates_untracked(&self) -> Vec<CrateNum>;
-
     // utility functions
     fn encode_metadata(&self, tcx: TyCtxt<'_>) -> EncodedMetadata;
 }
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index bc471aff2d0..80c4ff2ae5d 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -213,6 +213,8 @@ rustc_queries! {
     }
 
     query expn_that_defined(key: DefId) -> rustc_span::ExpnId {
+        // This query reads from untracked data in definitions.
+        eval_always
         desc { |tcx| "expansion that defined `{}`", tcx.def_path_str(key) }
     }
 
@@ -1446,6 +1448,7 @@ rustc_queries! {
         desc { "calculating the stability index for the local crate" }
     }
     query crates(_: ()) -> &'tcx [CrateNum] {
+        eval_always
         desc { "fetching all foreign CrateNum instances" }
     }
 
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 1afeb4a138f..f52686c9b5f 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1277,7 +1277,7 @@ impl<'tcx> TyCtxt<'tcx> {
         if crate_num == LOCAL_CRATE {
             self.sess.local_stable_crate_id()
         } else {
-            self.untracked_resolutions.cstore.stable_crate_id_untracked(crate_num)
+            self.untracked_resolutions.cstore.stable_crate_id(crate_num)
         }
     }
 
@@ -1290,10 +1290,7 @@ impl<'tcx> TyCtxt<'tcx> {
             (self.crate_name, self.sess.local_stable_crate_id())
         } else {
             let cstore = &self.untracked_resolutions.cstore;
-            (
-                cstore.crate_name_untracked(def_id.krate),
-                cstore.stable_crate_id_untracked(def_id.krate),
-            )
+            (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
         };
 
         format!(
@@ -2831,8 +2828,6 @@ pub fn provide(providers: &mut ty::query::Providers) {
     };
     providers.extern_mod_stmt_cnum =
         |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
-    providers.crates =
-        |tcx, ()| tcx.arena.alloc_slice(&tcx.resolutions(()).cstore.crates_untracked());
     providers.output_filenames = |tcx, ()| tcx.output_filenames.clone();
     providers.features_query = |tcx, ()| tcx.sess.features_untracked();
     providers.is_panic_runtime = |tcx, cnum| {
diff --git a/compiler/rustc_mir/src/interpret/memory.rs b/compiler/rustc_mir/src/interpret/memory.rs
index 5f719cc1607..194c478cc99 100644
--- a/compiler/rustc_mir/src/interpret/memory.rs
+++ b/compiler/rustc_mir/src/interpret/memory.rs
@@ -6,6 +6,7 @@
 //! integer. It is crucial that these operations call `check_align` *before*
 //! short-circuiting the empty case!
 
+use std::assert::assert_matches;
 use std::borrow::Cow;
 use std::collections::VecDeque;
 use std::convert::{TryFrom, TryInto};
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index f91bf0cbab7..35e7688fbe4 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -128,7 +128,7 @@ impl<'a> Resolver<'a> {
 
         let (name, parent) = if def_id.index == CRATE_DEF_INDEX {
             // This is the crate root
-            (self.cstore().crate_name_untracked(def_id.krate), None)
+            (self.cstore().crate_name(def_id.krate), None)
         } else {
             let def_key = self.cstore().def_key(def_id);
             let name = def_key
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 4c40d0c367e..474cd86f43b 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1084,6 +1084,8 @@ options! {
         "set the optimization fuel quota for a crate"),
     function_sections: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "whether each function should go in its own section"),
+    future_incompat_test: bool = (false, parse_bool, [UNTRACKED],
+        "forces all lints to be future incompatible, used for internal testing (default: no)"),
     gcc_ld: Option<LdImpl> = (None, parse_gcc_ld, [TRACKED], "implementation of ld used by cc"),
     graphviz_dark_mode: bool = (false, parse_bool, [UNTRACKED],
         "use dark-themed colors in graphviz output (default: no)"),
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 4b34a7dc894..d821e715622 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -19,7 +19,6 @@ use core::marker::{PhantomData, Unpin, Unsize};
 use core::mem::size_of_val;
 use core::mem::{self, align_of_val_raw};
 use core::ops::{CoerceUnsized, Deref, DispatchFromDyn, Receiver};
-#[cfg(not(no_global_oom_handling))]
 use core::pin::Pin;
 use core::ptr::{self, NonNull};
 #[cfg(not(no_global_oom_handling))]
@@ -494,6 +493,13 @@ impl<T> Arc<T> {
         unsafe { Pin::new_unchecked(Arc::new(data)) }
     }
 
+    /// Constructs a new `Pin<Arc<T>>`, return an error if allocation fails.
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    #[inline]
+    pub fn try_pin(data: T) -> Result<Pin<Arc<T>>, AllocError> {
+        unsafe { Ok(Pin::new_unchecked(Arc::try_new(data)?)) }
+    }
+
     /// Constructs a new `Arc<T>`, returning an error if allocation fails.
     ///
     /// # Examples
diff --git a/library/core/src/iter/adapters/fuse.rs b/library/core/src/iter/adapters/fuse.rs
index 0c21df4f12c..408328adeec 100644
--- a/library/core/src/iter/adapters/fuse.rs
+++ b/library/core/src/iter/adapters/fuse.rs
@@ -1,5 +1,5 @@
 use crate::intrinsics;
-use crate::iter::adapters::{zip::try_get_unchecked, InPlaceIterable, SourceIter};
+use crate::iter::adapters::zip::try_get_unchecked;
 use crate::iter::{
     DoubleEndedIterator, ExactSizeIterator, FusedIterator, TrustedLen, TrustedRandomAccess,
 };
@@ -14,7 +14,9 @@ use crate::ops::Try;
 #[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Fuse<I> {
-    // NOTE: for `I: FusedIterator`, this is always assumed `Some`!
+    // NOTE: for `I: FusedIterator`, we never bother setting `None`, but
+    // we still have to be prepared for that state due to variance.
+    // See rust-lang/rust#85863
     iter: Option<I>,
 }
 impl<I> Fuse<I> {
@@ -42,19 +44,19 @@ macro_rules! fuse {
     };
 }
 
-// NOTE: for `I: FusedIterator`, we assume that the iterator is always `Some`.
-// Implementing this as a directly-expanded macro helps codegen performance.
-macro_rules! unchecked {
-    ($self:ident) => {
-        match $self {
-            Fuse { iter: Some(iter) } => iter,
-            // SAFETY: the specialized iterator never sets `None`
-            Fuse { iter: None } => unsafe { intrinsics::unreachable() },
+/// Specialized macro that doesn't check if the expression is `None`.
+/// (We trust that a `FusedIterator` will fuse itself.)
+macro_rules! spec {
+    ($self:ident . iter . $($call:tt)+) => {
+        match $self.iter {
+            Some(ref mut iter) => iter.$($call)+,
+            None => None,
         }
     };
 }
 
-// Any implementation here is made internal to avoid exposing default fns outside this trait
+// Any specialized implementation here is made internal
+// to avoid exposing default fns outside this trait.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<I> Iterator for Fuse<I>
 where
@@ -74,17 +76,26 @@ where
 
     #[inline]
     fn last(self) -> Option<Self::Item> {
-        FuseImpl::last(self)
+        match self.iter {
+            Some(iter) => iter.last(),
+            None => None,
+        }
     }
 
     #[inline]
     fn count(self) -> usize {
-        FuseImpl::count(self)
+        match self.iter {
+            Some(iter) => iter.count(),
+            None => 0,
+        }
     }
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        FuseImpl::size_hint(self)
+        match self.iter {
+            Some(ref iter) => iter.size_hint(),
+            None => (0, Some(0)),
+        }
     }
 
     #[inline]
@@ -98,11 +109,14 @@ where
     }
 
     #[inline]
-    fn fold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
+    fn fold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
     where
         Fold: FnMut(Acc, Self::Item) -> Acc,
     {
-        FuseImpl::fold(self, acc, fold)
+        if let Some(iter) = self.iter {
+            acc = iter.fold(acc, fold);
+        }
+        acc
     }
 
     #[inline]
@@ -155,11 +169,14 @@ where
     }
 
     #[inline]
-    fn rfold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
+    fn rfold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
     where
         Fold: FnMut(Acc, Self::Item) -> Acc,
     {
-        FuseImpl::rfold(self, acc, fold)
+        if let Some(iter) = self.iter {
+            acc = iter.rfold(acc, fold);
+        }
+        acc
     }
 
     #[inline]
@@ -177,11 +194,17 @@ where
     I: ExactSizeIterator,
 {
     fn len(&self) -> usize {
-        FuseImpl::len(self)
+        match self.iter {
+            Some(ref iter) => iter.len(),
+            None => 0,
+        }
     }
 
     fn is_empty(&self) -> bool {
-        FuseImpl::is_empty(self)
+        match self.iter {
+            Some(ref iter) => iter.is_empty(),
+            None => true,
+        }
     }
 }
 
@@ -205,7 +228,10 @@ where
     const MAY_HAVE_SIDE_EFFECT: bool = I::MAY_HAVE_SIDE_EFFECT;
 }
 
-// Fuse specialization trait
+/// Fuse specialization trait
+///
+/// We only need to worry about `&mut self` methods, which
+/// may exhaust the iterator without consuming it.
 #[doc(hidden)]
 trait FuseImpl<I> {
     type Item;
@@ -213,17 +239,11 @@ trait FuseImpl<I> {
     // Functions specific to any normal Iterators
     fn next(&mut self) -> Option<Self::Item>;
     fn nth(&mut self, n: usize) -> Option<Self::Item>;
-    fn last(self) -> Option<Self::Item>;
-    fn count(self) -> usize;
-    fn size_hint(&self) -> (usize, Option<usize>);
     fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
     where
         Self: Sized,
         Fold: FnMut(Acc, Self::Item) -> R,
         R: Try<Output = Acc>;
-    fn fold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
-    where
-        Fold: FnMut(Acc, Self::Item) -> Acc;
     fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
     where
         P: FnMut(&Self::Item) -> bool;
@@ -241,25 +261,13 @@ trait FuseImpl<I> {
         Fold: FnMut(Acc, Self::Item) -> R,
         R: Try<Output = Acc>,
         I: DoubleEndedIterator;
-    fn rfold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
-    where
-        Fold: FnMut(Acc, Self::Item) -> Acc,
-        I: DoubleEndedIterator;
     fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
     where
         P: FnMut(&Self::Item) -> bool,
         I: DoubleEndedIterator;
-
-    // Functions specific to ExactSizeIterator
-    fn len(&self) -> usize
-    where
-        I: ExactSizeIterator;
-    fn is_empty(&self) -> bool
-    where
-        I: ExactSizeIterator;
 }
 
-// General Fuse impl
+/// General `Fuse` impl which sets `iter = None` when exhausted.
 #[doc(hidden)]
 impl<I> FuseImpl<I> for Fuse<I>
 where
@@ -278,30 +286,6 @@ where
     }
 
     #[inline]
-    default fn last(self) -> Option<I::Item> {
-        match self.iter {
-            Some(iter) => iter.last(),
-            None => None,
-        }
-    }
-
-    #[inline]
-    default fn count(self) -> usize {
-        match self.iter {
-            Some(iter) => iter.count(),
-            None => 0,
-        }
-    }
-
-    #[inline]
-    default fn size_hint(&self) -> (usize, Option<usize>) {
-        match self.iter {
-            Some(ref iter) => iter.size_hint(),
-            None => (0, Some(0)),
-        }
-    }
-
-    #[inline]
     default fn try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
     where
         Self: Sized,
@@ -316,17 +300,6 @@ where
     }
 
     #[inline]
-    default fn fold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
-    where
-        Fold: FnMut(Acc, Self::Item) -> Acc,
-    {
-        if let Some(iter) = self.iter {
-            acc = iter.fold(acc, fold);
-        }
-        acc
-    }
-
-    #[inline]
     default fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
     where
         P: FnMut(&Self::Item) -> bool,
@@ -366,18 +339,6 @@ where
     }
 
     #[inline]
-    default fn rfold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
-    where
-        Fold: FnMut(Acc, Self::Item) -> Acc,
-        I: DoubleEndedIterator,
-    {
-        if let Some(iter) = self.iter {
-            acc = iter.rfold(acc, fold);
-        }
-        acc
-    }
-
-    #[inline]
     default fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
     where
         P: FnMut(&Self::Item) -> bool,
@@ -385,30 +346,10 @@ where
     {
         fuse!(self.iter.rfind(predicate))
     }
-
-    #[inline]
-    default fn len(&self) -> usize
-    where
-        I: ExactSizeIterator,
-    {
-        match self.iter {
-            Some(ref iter) => iter.len(),
-            None => 0,
-        }
-    }
-
-    #[inline]
-    default fn is_empty(&self) -> bool
-    where
-        I: ExactSizeIterator,
-    {
-        match self.iter {
-            Some(ref iter) => iter.is_empty(),
-            None => true,
-        }
-    }
 }
 
+/// Specialized `Fuse` impl which doesn't bother clearing `iter` when exhausted.
+/// However, we must still be prepared for the possibility that it was already cleared!
 #[doc(hidden)]
 impl<I> FuseImpl<I> for Fuse<I>
 where
@@ -416,45 +357,25 @@ where
 {
     #[inline]
     fn next(&mut self) -> Option<<I as Iterator>::Item> {
-        unchecked!(self).next()
+        spec!(self.iter.next())
     }
 
     #[inline]
     fn nth(&mut self, n: usize) -> Option<I::Item> {
-        unchecked!(self).nth(n)
-    }
-
-    #[inline]
-    fn last(self) -> Option<I::Item> {
-        unchecked!(self).last()
+        spec!(self.iter.nth(n))
     }
 
     #[inline]
-    fn count(self) -> usize {
-        unchecked!(self).count()
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        unchecked!(self).size_hint()
-    }
-
-    #[inline]
-    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
+    fn try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
     where
         Self: Sized,
         Fold: FnMut(Acc, Self::Item) -> R,
         R: Try<Output = Acc>,
     {
-        unchecked!(self).try_fold(init, fold)
-    }
-
-    #[inline]
-    fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
-    where
-        Fold: FnMut(Acc, Self::Item) -> Acc,
-    {
-        unchecked!(self).fold(init, fold)
+        if let Some(ref mut iter) = self.iter {
+            acc = iter.try_fold(acc, fold)?;
+        }
+        try { acc }
     }
 
     #[inline]
@@ -462,7 +383,7 @@ where
     where
         P: FnMut(&Self::Item) -> bool,
     {
-        unchecked!(self).find(predicate)
+        spec!(self.iter.find(predicate))
     }
 
     #[inline]
@@ -470,7 +391,7 @@ where
     where
         I: DoubleEndedIterator,
     {
-        unchecked!(self).next_back()
+        spec!(self.iter.next_back())
     }
 
     #[inline]
@@ -478,27 +399,21 @@ where
     where
         I: DoubleEndedIterator,
     {
-        unchecked!(self).nth_back(n)
+        spec!(self.iter.nth_back(n))
     }
 
     #[inline]
-    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
+    fn try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
     where
         Self: Sized,
         Fold: FnMut(Acc, Self::Item) -> R,
         R: Try<Output = Acc>,
         I: DoubleEndedIterator,
     {
-        unchecked!(self).try_rfold(init, fold)
-    }
-
-    #[inline]
-    fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
-    where
-        Fold: FnMut(Acc, Self::Item) -> Acc,
-        I: DoubleEndedIterator,
-    {
-        unchecked!(self).rfold(init, fold)
+        if let Some(ref mut iter) = self.iter {
+            acc = iter.try_rfold(acc, fold)?;
+        }
+        try { acc }
     }
 
     #[inline]
@@ -507,43 +422,6 @@ where
         P: FnMut(&Self::Item) -> bool,
         I: DoubleEndedIterator,
     {
-        unchecked!(self).rfind(predicate)
-    }
-
-    #[inline]
-    fn len(&self) -> usize
-    where
-        I: ExactSizeIterator,
-    {
-        unchecked!(self).len()
-    }
-
-    #[inline]
-    fn is_empty(&self) -> bool
-    where
-        I: ExactSizeIterator,
-    {
-        unchecked!(self).is_empty()
+        spec!(self.iter.rfind(predicate))
     }
 }
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<S: Iterator, I: FusedIterator> SourceIter for Fuse<I>
-where
-    I: SourceIter<Source = S>,
-{
-    type Source = S;
-
-    #[inline]
-    unsafe fn as_inner(&mut self) -> &mut S {
-        match self.iter {
-            // SAFETY: unsafe function forwarding to unsafe function with the same requirements
-            Some(ref mut iter) => unsafe { SourceIter::as_inner(iter) },
-            // SAFETY: the specialized iterator never sets `None`
-            None => unsafe { intrinsics::unreachable() },
-        }
-    }
-}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<I: InPlaceIterable> InPlaceIterable for Fuse<I> {}
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 3557dbad90c..01d33409a42 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -179,6 +179,16 @@ use prelude::v1::*;
 #[macro_use]
 mod macros;
 
+// We don't export this through #[macro_export] for now, to avoid breakage.
+// See https://github.com/rust-lang/rust/issues/82913
+#[cfg(not(test))]
+#[unstable(feature = "assert_matches", issue = "82775")]
+/// Unstable module containing the unstable `assert_matches` macro.
+pub mod assert {
+    #[unstable(feature = "assert_matches", issue = "82775")]
+    pub use crate::macros::{assert_matches, debug_assert_matches};
+}
+
 #[macro_use]
 mod internal_macros;
 
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 7eb65483b99..8ce441e80bf 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -1,6 +1,7 @@
 #[doc = include_str!("panic.md")]
 #[macro_export]
-#[rustc_builtin_macro = "core_panic"]
+#[cfg_attr(bootstrap, rustc_builtin_macro = "core_panic")]
+#[cfg_attr(not(bootstrap), rustc_builtin_macro(core_panic))]
 #[allow_internal_unstable(edition_panic)]
 #[stable(feature = "core", since = "1.6.0")]
 #[rustc_diagnostic_item = "core_panic_macro"]
@@ -126,6 +127,8 @@ macro_rules! assert_ne {
 /// ```
 /// #![feature(assert_matches)]
 ///
+/// use std::assert::assert_matches;
+///
 /// let a = 1u32.checked_add(2);
 /// let b = 1u32.checked_sub(2);
 /// assert_matches!(a, Some(_));
@@ -134,10 +137,10 @@ macro_rules! assert_ne {
 /// let c = Ok("abc".to_string());
 /// assert_matches!(c, Ok(x) | Err(x) if x.len() < 100);
 /// ```
-#[macro_export]
 #[unstable(feature = "assert_matches", issue = "82775")]
 #[allow_internal_unstable(core_panic)]
-macro_rules! assert_matches {
+#[rustc_macro_transparency = "semitransparent"]
+pub macro assert_matches {
     ($left:expr, $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => ({
         match $left {
             $( $pattern )|+ $( if $guard )? => {}
@@ -149,7 +152,7 @@ macro_rules! assert_matches {
                 );
             }
         }
-    });
+    }),
     ($left:expr, $( $pattern:pat_param )|+ $( if $guard: expr )?, $($arg:tt)+) => ({
         match $left {
             $( $pattern )|+ $( if $guard )? => {}
@@ -161,7 +164,7 @@ macro_rules! assert_matches {
                 );
             }
         }
-    });
+    }),
 }
 
 /// Asserts that a boolean expression is `true` at runtime.
@@ -283,6 +286,8 @@ macro_rules! debug_assert_ne {
 /// ```
 /// #![feature(assert_matches)]
 ///
+/// use std::assert::debug_assert_matches;
+///
 /// let a = 1u32.checked_add(2);
 /// let b = 1u32.checked_sub(2);
 /// debug_assert_matches!(a, Some(_));
@@ -294,8 +299,9 @@ macro_rules! debug_assert_ne {
 #[macro_export]
 #[unstable(feature = "assert_matches", issue = "82775")]
 #[allow_internal_unstable(assert_matches)]
-macro_rules! debug_assert_matches {
-    ($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_matches!($($arg)*); })
+#[rustc_macro_transparency = "semitransparent"]
+pub macro debug_assert_matches($($arg:tt)*) {
+    if $crate::cfg!(debug_assertions) { $crate::assert::assert_matches!($($arg)*); }
 }
 
 /// Returns whether the given expression matches any of the given patterns.
diff --git a/library/core/src/slice/rotate.rs b/library/core/src/slice/rotate.rs
index a89596b15ef..7528927ef33 100644
--- a/library/core/src/slice/rotate.rs
+++ b/library/core/src/slice/rotate.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-undocumented-unsafe
-
 use crate::cmp;
 use crate::mem::{self, MaybeUninit};
 use crate::ptr;
@@ -79,8 +77,10 @@ pub unsafe fn ptr_rotate<T>(mut left: usize, mut mid: *mut T, mut right: usize)
             // the way until about `left + right == 32`, but the worst case performance breaks even
             // around 16. 24 was chosen as middle ground. If the size of `T` is larger than 4
             // `usize`s, this algorithm also outperforms other algorithms.
+            // SAFETY: callers must ensure `mid - left` is valid for reading and writing.
             let x = unsafe { mid.sub(left) };
             // beginning of first round
+            // SAFETY: see previous comment.
             let mut tmp: T = unsafe { x.read() };
             let mut i = right;
             // `gcd` can be found before hand by calculating `gcd(left + right, right)`,
@@ -92,6 +92,21 @@ pub unsafe fn ptr_rotate<T>(mut left: usize, mut mid: *mut T, mut right: usize)
             // the very end. This is possibly due to the fact that swapping or replacing temporaries
             // uses only one memory address in the loop instead of needing to manage two.
             loop {
+                // [long-safety-expl]
+                // SAFETY: callers must ensure `[left, left+mid+right)` are all valid for reading and
+                // writing.
+                //
+                // - `i` start with `right` so `mid-left <= x+i = x+right = mid-left+right < mid+right`
+                // - `i <= left+right-1` is always true
+                //   - if `i < left`, `right` is added so `i < left+right` and on the next
+                //     iteration `left` is removed from `i` so it doesn't go further
+                //   - if `i >= left`, `left` is removed immediately and so it doesn't go further.
+                // - overflows cannot happen for `i` since the function's safety contract ask for
+                //   `mid+right-1 = x+left+right` to be valid for writing
+                // - underflows cannot happen because `i` must be bigger or equal to `left` for
+                //   a substraction of `left` to happen.
+                //
+                // So `x+i` is valid for reading and writing if the caller respected the contract
                 tmp = unsafe { x.add(i).replace(tmp) };
                 // instead of incrementing `i` and then checking if it is outside the bounds, we
                 // check if `i` will go outside the bounds on the next increment. This prevents
@@ -100,6 +115,8 @@ pub unsafe fn ptr_rotate<T>(mut left: usize, mut mid: *mut T, mut right: usize)
                     i -= left;
                     if i == 0 {
                         // end of first round
+                        // SAFETY: tmp has been read from a valid source and x is valid for writing
+                        // according to the caller.
                         unsafe { x.write(tmp) };
                         break;
                     }
@@ -113,13 +130,24 @@ pub unsafe fn ptr_rotate<T>(mut left: usize, mut mid: *mut T, mut right: usize)
             }
             // finish the chunk with more rounds
             for start in 1..gcd {
+                // SAFETY: `gcd` is at most equal to `right` so all values in `1..gcd` are valid for
+                // reading and writing as per the function's safety contract, see [long-safety-expl]
+                // above
                 tmp = unsafe { x.add(start).read() };
+                // [safety-expl-addition]
+                //
+                // Here `start < gcd` so `start < right` so `i < right+right`: `right` being the
+                // greatest common divisor of `(left+right, right)` means that `left = right` so
+                // `i < left+right` so `x+i = mid-left+i` is always valid for reading and writing
+                // according to the function's safety contract.
                 i = start + right;
                 loop {
+                    // SAFETY: see [long-safety-expl] and [safety-expl-addition]
                     tmp = unsafe { x.add(i).replace(tmp) };
                     if i >= left {
                         i -= left;
                         if i == start {
+                            // SAFETY: see [long-safety-expl] and [safety-expl-addition]
                             unsafe { x.add(start).write(tmp) };
                             break;
                         }
@@ -135,14 +163,30 @@ pub unsafe fn ptr_rotate<T>(mut left: usize, mut mid: *mut T, mut right: usize)
             // The `[T; 0]` here is to ensure this is appropriately aligned for T
             let mut rawarray = MaybeUninit::<(BufType, [T; 0])>::uninit();
             let buf = rawarray.as_mut_ptr() as *mut T;
+            // SAFETY: `mid-left <= mid-left+right < mid+right`
             let dim = unsafe { mid.sub(left).add(right) };
             if left <= right {
+                // SAFETY:
+                //
+                // 1) The `else if` condition about the sizes ensures `[mid-left; left]` will fit in
+                //    `buf` without overflow and `buf` was created just above and so cannot be
+                //    overlapped with any value of `[mid-left; left]`
+                // 2) [mid-left, mid+right) are all valid for reading and writing and we don't care
+                //    about overlaps here.
+                // 3) The `if` condition about `left <= right` ensures writing `left` elements to
+                //    `dim = mid-left+right` is valid because:
+                //    - `buf` is valid and `left` elements were written in it in 1)
+                //    - `dim+left = mid-left+right+left = mid+right` and we write `[dim, dim+left)`
                 unsafe {
+                    // 1)
                     ptr::copy_nonoverlapping(mid.sub(left), buf, left);
+                    // 2)
                     ptr::copy(mid, mid.sub(left), right);
+                    // 3)
                     ptr::copy_nonoverlapping(buf, dim, left);
                 }
             } else {
+                // SAFETY: same reasoning as above but with `left` and `right` reversed
                 unsafe {
                     ptr::copy_nonoverlapping(mid, buf, right);
                     ptr::copy(mid.sub(left), dim, left);
@@ -156,6 +200,10 @@ pub unsafe fn ptr_rotate<T>(mut left: usize, mut mid: *mut T, mut right: usize)
             // of this algorithm would be, and swapping using that last chunk instead of swapping
             // adjacent chunks like this algorithm is doing, but this way is still faster.
             loop {
+                // SAFETY:
+                // `left >= right` so `[mid-right, mid+right)` is valid for reading and writing
+                // Substracting `right` from `mid` each turn is counterbalanced by the addition and
+                // check after it.
                 unsafe {
                     ptr::swap_nonoverlapping(mid.sub(right), mid, right);
                     mid = mid.sub(right);
@@ -168,6 +216,10 @@ pub unsafe fn ptr_rotate<T>(mut left: usize, mut mid: *mut T, mut right: usize)
         } else {
             // Algorithm 3, `left < right`
             loop {
+                // SAFETY: `[mid-left, mid+left)` is valid for reading and writing because
+                // `left < right` so `mid+left < mid+right`.
+                // Adding `left` to `mid` each turn is counterbalanced by the substraction and check
+                // after it.
                 unsafe {
                     ptr::swap_nonoverlapping(mid.sub(left), mid, left);
                     mid = mid.add(left);
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 8c120f4af28..472bca3460f 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -548,8 +548,8 @@ pub use std_detect::{
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow(deprecated, deprecated_in_future)]
 pub use core::{
-    assert_eq, assert_matches, assert_ne, debug_assert, debug_assert_eq, debug_assert_matches,
-    debug_assert_ne, matches, r#try, todo, unimplemented, unreachable, write, writeln,
+    assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, matches, r#try, todo,
+    unimplemented, unreachable, write, writeln,
 };
 
 // Re-export built-in macros defined through libcore.
diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs
index b2c5df5410d..7afe52a3fd6 100644
--- a/library/std/src/macros.rs
+++ b/library/std/src/macros.rs
@@ -6,7 +6,8 @@
 
 #[doc = include_str!("../../core/src/macros/panic.md")]
 #[macro_export]
-#[rustc_builtin_macro = "std_panic"]
+#[cfg_attr(bootstrap, rustc_builtin_macro = "std_panic")]
+#[cfg_attr(not(bootstrap), rustc_builtin_macro(std_panic))]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow_internal_unstable(edition_panic)]
 #[cfg_attr(not(test), rustc_diagnostic_item = "std_panic_macro")]
diff --git a/library/std/src/os/wasi/fs.rs b/library/std/src/os/wasi/fs.rs
index 7f26f419a4b..bd30d6ae3f3 100644
--- a/library/std/src/os/wasi/fs.rs
+++ b/library/std/src/os/wasi/fs.rs
@@ -1,7 +1,7 @@
 //! WASI-specific extensions to primitives in the `std::fs` module.
 
 #![deny(unsafe_op_in_unsafe_fn)]
-#![unstable(feature = "wasi_ext", issue = "none")]
+#![unstable(feature = "wasi_ext", issue = "71213")]
 
 use crate::ffi::OsStr;
 use crate::fs::{self, File, Metadata, OpenOptions};
diff --git a/library/std/src/os/wasi/io.rs b/library/std/src/os/wasi/io.rs
index b2e79cc1b4a..cf4501b98cb 100644
--- a/library/std/src/os/wasi/io.rs
+++ b/library/std/src/os/wasi/io.rs
@@ -1,7 +1,7 @@
 //! WASI-specific extensions to general I/O primitives
 
 #![deny(unsafe_op_in_unsafe_fn)]
-#![unstable(feature = "wasi_ext", issue = "none")]
+#![unstable(feature = "wasi_ext", issue = "71213")]
 
 use crate::fs;
 use crate::io;
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
index 6dcf0bdcba4..779b301ff61 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
@@ -72,7 +72,7 @@ ENV PATH="/node-v14.4.0-linux-x64/bin:${PATH}"
 # https://github.com/puppeteer/puppeteer/issues/375
 #
 # We also specify the version in case we need to update it to go around cache limitations.
-RUN npm install -g browser-ui-test@0.4.1 --unsafe-perm=true
+RUN npm install -g browser-ui-test@0.4.2 --unsafe-perm=true
 
 ENV RUST_CONFIGURE_ARGS \
   --build=x86_64-unknown-linux-gnu \
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index cd914f05e68..c5ca396e720 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -167,11 +167,7 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
 
     test_args.insert(0, "rustdoctest".to_string());
 
-    testing::test_main(
-        &test_args,
-        tests,
-        Some(testing::Options::new().display_output(display_warnings)),
-    );
+    test::test_main(&test_args, tests, Some(test::Options::new().display_output(display_warnings)));
 
     // Collect and warn about unused externs, but only if we've gotten
     // reports for each doctest
@@ -769,7 +765,7 @@ crate trait Tester {
 }
 
 crate struct Collector {
-    crate tests: Vec<testing::TestDescAndFn>,
+    crate tests: Vec<test::TestDescAndFn>,
 
     // The name of the test displayed to the user, separated by `::`.
     //
@@ -930,22 +926,22 @@ impl Tester for Collector {
         };
 
         debug!("creating test {}: {}", name, test);
-        self.tests.push(testing::TestDescAndFn {
-            desc: testing::TestDesc {
-                name: testing::DynTestName(name),
+        self.tests.push(test::TestDescAndFn {
+            desc: test::TestDesc {
+                name: test::DynTestName(name),
                 ignore: match config.ignore {
                     Ignore::All => true,
                     Ignore::None => false,
                     Ignore::Some(ref ignores) => ignores.iter().any(|s| target_str.contains(s)),
                 },
                 // compiler failures are test failures
-                should_panic: testing::ShouldPanic::No,
+                should_panic: test::ShouldPanic::No,
                 allow_fail: config.allow_fail,
                 compile_fail: config.compile_fail,
                 no_run,
-                test_type: testing::TestType::DocTest,
+                test_type: test::TestType::DocTest,
             },
-            testfn: testing::DynTestFn(box move || {
+            testfn: test::DynTestFn(box move || {
                 let report_unused_externs = |uext| {
                     unused_externs.lock().unwrap().push(uext);
                 };
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 9fff508165a..3b599e4997a 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -33,6 +33,7 @@ use std::str;
 
 use crate::clean::RenderedLink;
 use crate::doctest;
+use crate::html::escape::Escape;
 use crate::html::highlight;
 use crate::html::toc::TocBuilder;
 
@@ -207,26 +208,11 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
         let should_panic;
         let ignore;
         let edition;
-        if let Some(Event::Start(Tag::CodeBlock(kind))) = event {
-            let parse_result = match kind {
-                CodeBlockKind::Fenced(ref lang) => {
-                    LangString::parse_without_check(&lang, self.check_error_codes, false)
-                }
-                CodeBlockKind::Indented => Default::default(),
-            };
-            if !parse_result.rust {
-                return Some(Event::Start(Tag::CodeBlock(kind)));
-            }
-            compile_fail = parse_result.compile_fail;
-            should_panic = parse_result.should_panic;
-            ignore = parse_result.ignore;
-            edition = parse_result.edition;
+        let kind = if let Some(Event::Start(Tag::CodeBlock(kind))) = event {
+            kind
         } else {
             return event;
-        }
-
-        let explicit_edition = edition.is_some();
-        let edition = edition.unwrap_or(self.edition);
+        };
 
         let mut origtext = String::new();
         for event in &mut self.inner {
@@ -241,6 +227,35 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
         let lines = origtext.lines().filter_map(|l| map_line(l).for_html());
         let text = lines.collect::<Vec<Cow<'_, str>>>().join("\n");
 
+        let parse_result = match kind {
+            CodeBlockKind::Fenced(ref lang) => {
+                let parse_result =
+                    LangString::parse_without_check(&lang, self.check_error_codes, false);
+                if !parse_result.rust {
+                    return Some(Event::Html(
+                        format!(
+                            "<div class=\"example-wrap\">\
+                                 <pre{}>{}</pre>\
+                             </div>",
+                            format!(" class=\"language-{}\"", lang),
+                            Escape(&text),
+                        )
+                        .into(),
+                    ));
+                }
+                parse_result
+            }
+            CodeBlockKind::Indented => Default::default(),
+        };
+
+        compile_fail = parse_result.compile_fail;
+        should_panic = parse_result.should_panic;
+        ignore = parse_result.ignore;
+        edition = parse_result.edition;
+
+        let explicit_edition = edition.is_some();
+        let edition = edition.unwrap_or(self.edition);
+
         let playground_button = self.playground.as_ref().and_then(|playground| {
             let krate = &playground.crate_name;
             let url = &playground.url;
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 66dfd2fac84..208e8f723f4 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -435,7 +435,7 @@ nav.sub {
 	border-bottom-left-radius: 5px;
 }
 
-.rustdoc:not(.source) .example-wrap > pre.rust {
+.rustdoc:not(.source) .example-wrap > pre:not(.line-number) {
 	width: 100%;
 	overflow-x: auto;
 }
diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css
index 9da3fe07ade..8296c3f91ca 100644
--- a/src/librustdoc/html/static/css/themes/ayu.css
+++ b/src/librustdoc/html/static/css/themes/ayu.css
@@ -34,7 +34,7 @@ h4 {
 	background: rgba(0, 0, 0, 0);
 }
 
-code {
+.docblock code {
 	color: #ffb454;
 }
 h3 > code, h4 > code, h5 > code {
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index bc635190f42..d4d87819c0d 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -53,11 +53,11 @@ extern crate rustc_parse;
 extern crate rustc_passes;
 extern crate rustc_resolve;
 extern crate rustc_session;
-extern crate rustc_span as rustc_span;
+extern crate rustc_span;
 extern crate rustc_target;
 extern crate rustc_trait_selection;
 extern crate rustc_typeck;
-extern crate test as testing;
+extern crate test;
 
 #[cfg(feature = "jemalloc")]
 extern crate tikv_jemalloc_sys;
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index 5da3a75e876..45966c0058d 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -136,10 +136,10 @@ crate fn test(mut options: Options) -> Result<(), String> {
     find_testable_code(&input_str, &mut collector, codes, options.enable_per_target_ignores, None);
 
     options.test_args.insert(0, "rustdoctest".to_string());
-    testing::test_main(
+    test::test_main(
         &options.test_args,
         collector.tests,
-        Some(testing::Options::new().display_output(options.display_warnings)),
+        Some(test::Options::new().display_output(options.display_warnings)),
     );
     Ok(())
 }
diff --git a/src/test/debuginfo/function-names.rs b/src/test/debuginfo/function-names.rs
index 26317f5c3ff..20a49f0bd26 100644
--- a/src/test/debuginfo/function-names.rs
+++ b/src/test/debuginfo/function-names.rs
@@ -33,6 +33,13 @@
 // Generator
 // Generators don't seem to appear in GDB's symbol table.
 
+// Const generic parameter
+// gdb-command:info functions -q function_names::const_generic_fn.*
+// gdb-check:[...]static fn function_names::const_generic_fn_bool();
+// gdb-check:[...]static fn function_names::const_generic_fn_non_int();
+// gdb-check:[...]static fn function_names::const_generic_fn_signed_int();
+// gdb-check:[...]static fn function_names::const_generic_fn_unsigned_int();
+
 // === CDB TESTS ===================================================================================
 
 // Top-level function
@@ -49,9 +56,9 @@
 
 // Trait implementations
 // cdb-command:x a!function_names::*::trait_function*
-// cdb-check:[...] a!function_names::impl$6::trait_function<i32, 0x1> (void)
 // cdb-check:[...] a!function_names::impl$3::trait_function<i32> (void)
 // cdb-check:[...] a!function_names::impl$1::trait_function (void)
+// cdb-check:[...] a!function_names::impl$6::trait_function<i32, 1> (void)
 // cdb-check:[...] a!function_names::impl$5::trait_function3<function_names::TestStruct1> (void)
 // cdb-check:[...] a!function_names::Mod1::impl$1::trait_function (void)
 
@@ -65,10 +72,18 @@
 // cdb-command:x a!function_names::*::generator*
 // cdb-check:[...] a!function_names::main::generator$1 (void)
 
+// Const generic parameter
+// cdb-command:x a!function_names::const_generic_fn*
+// cdb-check:[...] a!function_names::const_generic_fn_bool<false> (void)
+// cdb-check:[...] a!function_names::const_generic_fn_non_int<CONST$fe3cfa0214ac55c7> (void)
+// cdb-check:[...] a!function_names::const_generic_fn_unsigned_int<14> (void)
+// cdb-check:[...] a!function_names::const_generic_fn_signed_int<-7> (void)
+
 #![allow(unused_variables)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
-#![feature(generators, generator_trait)]
+#![feature(const_generics, generators, generator_trait)]
+#![allow(incomplete_features)] // for const_generics
 
 use Mod1::TestTrait2;
 use std::ops::Generator;
@@ -97,6 +112,12 @@ fn main() {
     // Generator
     let mut generator = || { yield; return; };
     Pin::new(&mut generator).resume(());
+
+    // Const generic functions
+    const_generic_fn_bool::<false>();
+    const_generic_fn_non_int::<{()}>();
+    const_generic_fn_signed_int::<-7>();
+    const_generic_fn_unsigned_int::<14>();
 }
 
 struct TestStruct1;
@@ -173,3 +194,8 @@ fn generic_func<T>(value: T) -> T {
 
     value
 }
+
+fn const_generic_fn_bool<const C: bool>() {}
+fn const_generic_fn_non_int<const C: ()>() {}
+fn const_generic_fn_signed_int<const C: i64>() {}
+fn const_generic_fn_unsigned_int<const C: u32>() {}
diff --git a/src/test/rustdoc-gui/ayu-code-tag-colors.goml b/src/test/rustdoc-gui/ayu-code-tag-colors.goml
new file mode 100644
index 00000000000..50af36fa3d6
--- /dev/null
+++ b/src/test/rustdoc-gui/ayu-code-tag-colors.goml
@@ -0,0 +1,13 @@
+// The ayu theme has a different color for the "<code>" tags in the doc blocks. We need to
+// check that the rule isn't applied on other "<code>" elements.
+goto: file://|DOC_PATH|/test_docs/enum.AnEnum.html
+// We need to show the text, otherwise the colors aren't "computed" by the web browser.
+show-text: true
+// We set the theme to ayu.
+local-storage: {"rustdoc-theme": "ayu", "rustdoc-preferred-dark-theme": "ayu", "rustdoc-use-system-theme": "false"}
+// We reload to get the text appearing and the theme applied.
+reload:
+
+assert-css: (".docblock code", {"color": "rgb(255, 180, 84)"}, ALL)
+// It includes variants and the "titles" as well (for example: "impl RefUnwindSafe for AnEnum").
+assert-css: ("div:not(.docblock) > code", {"color": "rgb(197, 197, 197)"}, ALL)
diff --git a/src/test/rustdoc-gui/code-blocks-overflow.goml b/src/test/rustdoc-gui/code-blocks-overflow.goml
new file mode 100644
index 00000000000..ee4dad444e9
--- /dev/null
+++ b/src/test/rustdoc-gui/code-blocks-overflow.goml
@@ -0,0 +1,8 @@
+// This test ensures that codeblocks content don't overflow.
+goto: file://|DOC_PATH|/lib2/sub_mod/struct.Foo.html
+size: (1080, 600)
+// There should be two codeblocks: a rust one and a non-rust one.
+assert-count: (".docblock > .example-wrap", 2)
+assert: ".docblock > .example-wrap > .language-txt"
+assert: ".docblock > .example-wrap > .rust-example-rendered"
+assert-css: (".docblock > .example-wrap > pre", {"width": "796px", "overflow-x": "auto"}, ALL)
diff --git a/src/test/rustdoc-gui/src/lib2/lib.rs b/src/test/rustdoc-gui/src/lib2/lib.rs
index 72ef3cbd202..ec8ab339e28 100644
--- a/src/test/rustdoc-gui/src/lib2/lib.rs
+++ b/src/test/rustdoc-gui/src/lib2/lib.rs
@@ -1,3 +1,5 @@
+// ignore-tidy-linelength
+
 pub mod module {
     pub mod sub_module {
         pub mod sub_sub_module {
@@ -32,4 +34,16 @@ impl Trait for Foo {
     const Y: u32 = 0;
 }
 
+
 impl implementors::Whatever for Foo {}
+
+pub mod sub_mod {
+    /// ```txt
+    /// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+    /// ```
+    ///
+    /// ```
+    /// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+    /// ```
+    pub struct Foo;
+}
diff --git a/src/test/rustdoc-gui/src/test_docs/lib.rs b/src/test/rustdoc-gui/src/test_docs/lib.rs
index 1b9f652120e..85dd8805fbc 100644
--- a/src/test/rustdoc-gui/src/test_docs/lib.rs
+++ b/src/test/rustdoc-gui/src/test_docs/lib.rs
@@ -96,6 +96,7 @@ pub fn check_list_code_block() {}
 #[doc(cfg(unix))]
 pub fn replaced_function() {}
 
+/// Some doc with `code`!
 pub enum AnEnum {
     WithVariants { and: usize, sub: usize, variants: usize },
 }
diff --git a/src/test/ui/crate-loading/auxiliary/proc-macro.rs b/src/test/ui/crate-loading/auxiliary/proc-macro.rs
new file mode 100644
index 00000000000..52631de5757
--- /dev/null
+++ b/src/test/ui/crate-loading/auxiliary/proc-macro.rs
@@ -0,0 +1,12 @@
+// force-host
+// no-prefer-dynamic
+#![crate_name = "reproduction"]
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::TokenStream;
+
+#[proc_macro]
+pub fn mac(input: TokenStream) -> TokenStream {
+    input
+}
diff --git a/src/test/ui/crate-loading/cross-compiled-proc-macro.rs b/src/test/ui/crate-loading/cross-compiled-proc-macro.rs
new file mode 100644
index 00000000000..c1f4331438e
--- /dev/null
+++ b/src/test/ui/crate-loading/cross-compiled-proc-macro.rs
@@ -0,0 +1,8 @@
+// edition:2018
+// compile-flags:--extern reproduction
+// aux-build:proc-macro.rs
+// check-pass
+
+reproduction::mac!();
+
+fn main() {}
diff --git a/src/test/ui/deriving/deriving-with-helper.rs b/src/test/ui/deriving/deriving-with-helper.rs
new file mode 100644
index 00000000000..ea74a15624c
--- /dev/null
+++ b/src/test/ui/deriving/deriving-with-helper.rs
@@ -0,0 +1,36 @@
+// check-pass
+// compile-flags: --crate-type=lib
+
+#![feature(decl_macro)]
+#![feature(lang_items)]
+#![feature(no_core)]
+#![feature(rustc_attrs)]
+
+#![no_core]
+
+#[rustc_builtin_macro]
+macro derive() {}
+
+#[rustc_builtin_macro(Default, attributes(default))]
+macro Default() {}
+
+mod default {
+    pub trait Default {
+        fn default() -> Self;
+    }
+
+    impl Default for u8 {
+        fn default() -> u8 {
+            0
+        }
+    }
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+#[derive(Default)]
+struct S {
+    #[default] // OK
+    field: u8,
+}
diff --git a/src/test/ui/lint/future-incompat-test.rs b/src/test/ui/lint/future-incompat-test.rs
new file mode 100644
index 00000000000..ce8c118dab2
--- /dev/null
+++ b/src/test/ui/lint/future-incompat-test.rs
@@ -0,0 +1,10 @@
+// compile-flags: -Zfuture-incompat-test -Zemit-future-incompat-report
+// check-pass
+
+// The `-Zfuture-incompat-test flag causes any normal warning to be included
+// in the future-incompatible report. The stderr output here should mention
+// the future incompatible report (as extracted by compiletest).
+
+fn main() {
+    let x = 1;
+}
diff --git a/src/test/ui/lint/future-incompat-test.stderr b/src/test/ui/lint/future-incompat-test.stderr
new file mode 100644
index 00000000000..52674a84384
--- /dev/null
+++ b/src/test/ui/lint/future-incompat-test.stderr
@@ -0,0 +1,9 @@
+Future incompatibility report: Future breakage diagnostic:
+warning: unused variable: `x`
+  --> $DIR/future-incompat-test.rs:9:9
+   |
+LL |     let x = 1;
+   |         ^ help: if this is intentional, prefix it with an underscore: `_x`
+   |
+   = note: `-A unused-variables` implied by `-A unused`
+
diff --git a/src/test/ui/macros/assert-matches-macro-msg.rs b/src/test/ui/macros/assert-matches-macro-msg.rs
index 43be9532f5d..714a6561a6d 100644
--- a/src/test/ui/macros/assert-matches-macro-msg.rs
+++ b/src/test/ui/macros/assert-matches-macro-msg.rs
@@ -6,6 +6,8 @@
 
 #![feature(assert_matches)]
 
+use std::assert::assert_matches;
+
 fn main() {
     assert_matches!(1 + 1, 3, "1 + 1 definitely should be 3");
 }
diff --git a/src/test/ui/matches2021.rs b/src/test/ui/matches2021.rs
index 1090b1578ba..a6fa5128d2f 100644
--- a/src/test/ui/matches2021.rs
+++ b/src/test/ui/matches2021.rs
@@ -6,6 +6,8 @@
 
 #![feature(assert_matches)]
 
+use std::assert::assert_matches;
+
 fn main() {
     assert!(matches!((), ()));
     assert_matches!((), ());
diff --git a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stderr b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stderr
index e764480e8e5..070b0667213 100644
--- a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stderr
+++ b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stderr
@@ -81,7 +81,7 @@ LL |     tuple_from_req!(Foo);
 
 warning: 5 warnings emitted
 
-Future incompatibility report: Future breakage date: None, diagnostic:
+Future incompatibility report: Future breakage diagnostic:
 warning: using an old version of `time-macros-impl`
   --> $DIR/time-macros-impl/src/lib.rs:5:32
    |
@@ -99,7 +99,7 @@ LL |     impl_macros!(Foo);
    = note: the `time-macros-impl` crate will stop compiling in futures version of Rust. Please update to the latest version of the `time` crate to avoid breakage
    = note: this warning originates in the macro `impl_macros` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-Future breakage date: None, diagnostic:
+Future breakage diagnostic:
 warning: using an old version of `time-macros-impl`
   --> $DIR/time-macros-impl-0.1.0/src/lib.rs:5:32
    |
@@ -116,7 +116,7 @@ LL |     impl_macros!(Foo);
    = note: the `time-macros-impl` crate will stop compiling in futures version of Rust. Please update to the latest version of the `time` crate to avoid breakage
    = note: this warning originates in the macro `impl_macros` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-Future breakage date: None, diagnostic:
+Future breakage diagnostic:
 warning: using an old version of `js-sys`
   --> $DIR/js-sys-0.3.17/src/lib.rs:5:32
    |
@@ -133,7 +133,7 @@ LL |     arrays!(Foo);
    = note: older versions of the `js-sys` crate will stop compiling in future versions of Rust; please update to `js-sys` v0.3.40 or above
    = note: this warning originates in the macro `arrays` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-Future breakage date: None, diagnostic:
+Future breakage diagnostic:
 warning: using an old version of `actix-web`
   --> $DIR/actix-web/src/extract.rs:5:34
    |
@@ -150,7 +150,7 @@ LL |     tuple_from_req!(Foo);
    = note: the version of `actix-web` you are using might stop compiling in future versions of Rust; please update to the latest version of the `actix-web` crate to avoid breakage
    = note: this warning originates in the macro `tuple_from_req` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-Future breakage date: None, diagnostic:
+Future breakage diagnostic:
 warning: using an old version of `actix-web`
   --> $DIR/actix-web-2.0.0/src/extract.rs:5:34
    |
diff --git a/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr
index 0b930705e35..4d6edab08e2 100644
--- a/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr
+++ b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr
@@ -11,7 +11,7 @@ LL | enum ProceduralMasqueradeDummyType {
 
 warning: 1 warning emitted
 
-Future incompatibility report: Future breakage date: None, diagnostic:
+Future incompatibility report: Future breakage diagnostic:
 warning: using `procedural-masquerade` crate
   --> $DIR/issue-73933-procedural-masquerade.rs:8:6
    |
diff --git a/src/test/ui/resolve/resolve-hint-macro.rs b/src/test/ui/resolve/resolve-hint-macro.rs
index 6155ae7bcdf..5532c8b90e3 100644
--- a/src/test/ui/resolve/resolve-hint-macro.rs
+++ b/src/test/ui/resolve/resolve-hint-macro.rs
@@ -1,4 +1,4 @@
 fn main() {
-    assert(true);
-    //~^ ERROR expected function, found macro `assert`
+    assert_eq(1, 1);
+    //~^ ERROR expected function, found macro `assert_eq`
 }
diff --git a/src/test/ui/resolve/resolve-hint-macro.stderr b/src/test/ui/resolve/resolve-hint-macro.stderr
index 7d35ce7e65e..efcfc7198ab 100644
--- a/src/test/ui/resolve/resolve-hint-macro.stderr
+++ b/src/test/ui/resolve/resolve-hint-macro.stderr
@@ -1,13 +1,13 @@
-error[E0423]: expected function, found macro `assert`
+error[E0423]: expected function, found macro `assert_eq`
   --> $DIR/resolve-hint-macro.rs:2:5
    |
-LL |     assert(true);
-   |     ^^^^^^ not a function
+LL |     assert_eq(1, 1);
+   |     ^^^^^^^^^ not a function
    |
 help: use `!` to invoke the macro
    |
-LL |     assert!(true);
-   |           ^
+LL |     assert_eq!(1, 1);
+   |              ^
 
 error: aborting due to previous error
 
diff --git a/src/tools/compiletest/src/json.rs b/src/tools/compiletest/src/json.rs
index 8d23227fdb8..dc6d67983c5 100644
--- a/src/tools/compiletest/src/json.rs
+++ b/src/tools/compiletest/src/json.rs
@@ -43,7 +43,6 @@ struct FutureIncompatReport {
 
 #[derive(Deserialize)]
 struct FutureBreakageItem {
-    future_breakage_date: Option<String>,
     diagnostic: Diagnostic,
 }
 
@@ -104,9 +103,7 @@ pub fn extract_rendered(output: &str) -> String {
                                 .into_iter()
                                 .map(|item| {
                                     format!(
-                                        "Future breakage date: {}, diagnostic:\n{}",
-                                        item.future_breakage_date
-                                            .unwrap_or_else(|| "None".to_string()),
+                                        "Future breakage diagnostic:\n{}",
                                         item.diagnostic
                                             .rendered
                                             .unwrap_or_else(|| "Not rendered".to_string())