about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-07-14 18:36:44 +0000
committerbors <bors@rust-lang.org>2021-07-14 18:36:44 +0000
commite87188c252a3b6dea8ed54d7915fbc2cfb61443b (patch)
treed1a7dcc583bbe747a2b06f9d31d45f13a65da0f3
parent4f0c568785adcc0a123cac9d47047020b7a24821 (diff)
parentac6672b74631cfcdbfd042724e29969b193cefa1 (diff)
downloadrust-e87188c252a3b6dea8ed54d7915fbc2cfb61443b.tar.gz
rust-e87188c252a3b6dea8ed54d7915fbc2cfb61443b.zip
Auto merge of #87133 - GuillaumeGomez:rollup-pfz9jbk, r=GuillaumeGomez
Rollup of 6 pull requests

Successful merges:

 - #87027 (expand: Support helper attributes for built-in derive macros)
 - #87056 (Fix codeblocks overflow)
 - #87117 (Shrink the CrateStore dynamic interface.)
 - #87120 (rustdoc: Remove unnecessary `extern crate` aliases)
 - #87125 (Fix Ayu theme `<code>` color)
 - #87130 (Update browser-ui-test package version)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_builtin_macros/src/proc_macro_harness.rs83
-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_metadata/src/creader.rs2
-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/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_resolve/src/build_reduced_graph.rs2
-rw-r--r--library/core/src/macros/mod.rs3
-rw-r--r--library/std/src/macros.rs3
-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/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/deriving/deriving-with-helper.rs36
26 files changed, 267 insertions, 174 deletions
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_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_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 250af3c6e89..70d29f9d7ca 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`")
     }
 
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/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_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/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 7eb65483b99..7d22bfedb93 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"]
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/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/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/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,
+}