about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-08-19 20:31:05 +0000
committerbors <bors@rust-lang.org>2021-08-19 20:31:05 +0000
commit6d64f7f695943541fe12bb960971403f440d7225 (patch)
treee13fba589fabe127b60c3c2756d3cd969fd2a9f7
parent7960030d6915a771f5ab72c3897a7ed50c3ed4bd (diff)
parent1095bb1eb25b38a221e35588530269c6219a95a1 (diff)
downloadrust-6d64f7f695943541fe12bb960971403f440d7225.tar.gz
rust-6d64f7f695943541fe12bb960971403f440d7225.zip
Auto merge of #88165 - GuillaumeGomez:rollup-4o0v2ps, r=GuillaumeGomez
Rollup of 8 pull requests

Successful merges:

 - #86123 (Preserve more spans in internal `rustc_queries!` macro)
 - #87874 (Add TcpStream type to TcpListener::incoming docs)
 - #88034 (rustc_privacy: Replace `HirId`s and `DefId`s with `LocalDefId`s where possible)
 - #88050 (Remove `HashStable` impls for `FileName` and `RealFileName`)
 - #88093 ([rustdoc] Wrap code blocks in `<code>` tag)
 - #88146 (Add tests for some `feature(const_evaluatable_checked)` incr comp issues)
 - #88153 (Update .mailmap)
 - #88159 (Use a trait instead of the now disallowed missing trait there)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--.mailmap1
-rw-r--r--compiler/rustc_macros/src/query.rs104
-rw-r--r--compiler/rustc_privacy/src/lib.rs139
-rw-r--r--compiler/rustc_span/src/lib.rs4
-rw-r--r--library/std/src/net/tcp.rs21
-rw-r--r--src/librustdoc/html/highlight.rs7
-rw-r--r--src/librustdoc/html/markdown.rs2
-rw-r--r--src/librustdoc/html/render/print_item.rs550
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css1
-rw-r--r--src/test/incremental/const-generics/hash-tyvid-regression-1.rs15
-rw-r--r--src/test/incremental/const-generics/hash-tyvid-regression-1.stderr35
-rw-r--r--src/test/incremental/const-generics/hash-tyvid-regression-2.rs18
-rw-r--r--src/test/incremental/const-generics/hash-tyvid-regression-2.stderr11
-rw-r--r--src/test/incremental/const-generics/hash-tyvid-regression-3.rs26
-rw-r--r--src/test/incremental/const-generics/hash-tyvid-regression-3.stderr12
-rw-r--r--src/test/incremental/const-generics/hash-tyvid-regression-4.rs40
-rw-r--r--src/test/incremental/const-generics/hash-tyvid-regression-4.stderr12
-rw-r--r--src/test/rustdoc-gui/code-tags.goml20
-rw-r--r--src/test/rustdoc-gui/source-code-page.goml2
-rw-r--r--src/test/ui/type-alias-impl-trait/unused_generic_param.rs9
-rw-r--r--src/test/ui/type-alias-impl-trait/unused_generic_param.stderr14
21 files changed, 638 insertions, 405 deletions
diff --git a/.mailmap b/.mailmap
index 56ac5296774..d1f5ca9371f 100644
--- a/.mailmap
+++ b/.mailmap
@@ -113,6 +113,7 @@ Hanna Kruppe <hanna.kruppe@gmail.com> <robin.kruppe@gmail.com>
 Heather <heather@cynede.net> <Cynede@Gentoo.org>
 Heather <heather@cynede.net> <Heather@cynede.net>
 Herman J. Radtke III <herman@hermanradtke.com> Herman J. Radtke III <hermanradtke@gmail.com>
+Hirochika Matsumoto <git@hkmatsumoto.com> <matsujika@gmail.com>
 Ian Jackson <ijackson@chiark.greenend.org.uk> <ian.jackson@citrix.com>
 Ian Jackson <ijackson@chiark.greenend.org.uk> <ijackson+github@slimy.greenend.org.uk>
 Ian Jackson <ijackson@chiark.greenend.org.uk> <iwj@xenproject.org>
diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs
index dcd36d61bc6..7ad36973f46 100644
--- a/compiler/rustc_macros/src/query.rs
+++ b/compiler/rustc_macros/src/query.rs
@@ -1,6 +1,6 @@
 use proc_macro::TokenStream;
 use proc_macro2::{Delimiter, TokenTree};
-use quote::quote;
+use quote::{quote, quote_spanned};
 use syn::parse::{Parse, ParseStream, Result};
 use syn::punctuated::Punctuated;
 use syn::spanned::Spanned;
@@ -42,19 +42,19 @@ enum QueryModifier {
     LoadCached(Ident, Ident, Block),
 
     /// A cycle error for this query aborting the compilation with a fatal error.
-    FatalCycle,
+    FatalCycle(Ident),
 
     /// A cycle error results in a delay_bug call
-    CycleDelayBug,
+    CycleDelayBug(Ident),
 
     /// Don't hash the result, instead just mark a query red if it runs
-    NoHash,
+    NoHash(Ident),
 
     /// Generate a dep node based on the dependencies of the query
-    Anon,
+    Anon(Ident),
 
     /// Always evaluate the query, ignoring its dependencies
-    EvalAlways,
+    EvalAlways(Ident),
 }
 
 impl Parse for QueryModifier {
@@ -111,15 +111,15 @@ impl Parse for QueryModifier {
             let ty = args.parse()?;
             Ok(QueryModifier::Storage(ty))
         } else if modifier == "fatal_cycle" {
-            Ok(QueryModifier::FatalCycle)
+            Ok(QueryModifier::FatalCycle(modifier))
         } else if modifier == "cycle_delay_bug" {
-            Ok(QueryModifier::CycleDelayBug)
+            Ok(QueryModifier::CycleDelayBug(modifier))
         } else if modifier == "no_hash" {
-            Ok(QueryModifier::NoHash)
+            Ok(QueryModifier::NoHash(modifier))
         } else if modifier == "anon" {
-            Ok(QueryModifier::Anon)
+            Ok(QueryModifier::Anon(modifier))
         } else if modifier == "eval_always" {
-            Ok(QueryModifier::EvalAlways)
+            Ok(QueryModifier::EvalAlways(modifier))
         } else {
             Err(Error::new(modifier.span(), "unknown query modifier"))
         }
@@ -203,19 +203,19 @@ struct QueryModifiers {
     load_cached: Option<(Ident, Ident, Block)>,
 
     /// A cycle error for this query aborting the compilation with a fatal error.
-    fatal_cycle: bool,
+    fatal_cycle: Option<Ident>,
 
     /// A cycle error results in a delay_bug call
-    cycle_delay_bug: bool,
+    cycle_delay_bug: Option<Ident>,
 
     /// Don't hash the result, instead just mark a query red if it runs
-    no_hash: bool,
+    no_hash: Option<Ident>,
 
     /// Generate a dep node based on the dependencies of the query
-    anon: bool,
+    anon: Option<Ident>,
 
     // Always evaluate the query, ignoring its dependencies
-    eval_always: bool,
+    eval_always: Option<Ident>,
 }
 
 /// Process query modifiers into a struct, erroring on duplicates
@@ -224,11 +224,11 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
     let mut storage = None;
     let mut cache = None;
     let mut desc = None;
-    let mut fatal_cycle = false;
-    let mut cycle_delay_bug = false;
-    let mut no_hash = false;
-    let mut anon = false;
-    let mut eval_always = false;
+    let mut fatal_cycle = None;
+    let mut cycle_delay_bug = None;
+    let mut no_hash = None;
+    let mut anon = None;
+    let mut eval_always = None;
     for modifier in query.modifiers.0.drain(..) {
         match modifier {
             QueryModifier::LoadCached(tcx, id, block) => {
@@ -289,35 +289,35 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
                 }
                 desc = Some((tcx, list));
             }
-            QueryModifier::FatalCycle => {
-                if fatal_cycle {
+            QueryModifier::FatalCycle(ident) => {
+                if fatal_cycle.is_some() {
                     panic!("duplicate modifier `fatal_cycle` for query `{}`", query.name);
                 }
-                fatal_cycle = true;
+                fatal_cycle = Some(ident);
             }
-            QueryModifier::CycleDelayBug => {
-                if cycle_delay_bug {
+            QueryModifier::CycleDelayBug(ident) => {
+                if cycle_delay_bug.is_some() {
                     panic!("duplicate modifier `cycle_delay_bug` for query `{}`", query.name);
                 }
-                cycle_delay_bug = true;
+                cycle_delay_bug = Some(ident);
             }
-            QueryModifier::NoHash => {
-                if no_hash {
+            QueryModifier::NoHash(ident) => {
+                if no_hash.is_some() {
                     panic!("duplicate modifier `no_hash` for query `{}`", query.name);
                 }
-                no_hash = true;
+                no_hash = Some(ident);
             }
-            QueryModifier::Anon => {
-                if anon {
+            QueryModifier::Anon(ident) => {
+                if anon.is_some() {
                     panic!("duplicate modifier `anon` for query `{}`", query.name);
                 }
-                anon = true;
+                anon = Some(ident);
             }
-            QueryModifier::EvalAlways => {
-                if eval_always {
+            QueryModifier::EvalAlways(ident) => {
+                if eval_always.is_some() {
                     panic!("duplicate modifier `eval_always` for query `{}`", query.name);
                 }
-                eval_always = true;
+                eval_always = Some(ident);
             }
         }
     }
@@ -454,31 +454,39 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
         let mut attributes = Vec::new();
 
         // Pass on the fatal_cycle modifier
-        if modifiers.fatal_cycle {
-            attributes.push(quote! { fatal_cycle });
+        if let Some(fatal_cycle) = &modifiers.fatal_cycle {
+            attributes.push(quote! { #fatal_cycle });
         };
         // Pass on the storage modifier
         if let Some(ref ty) = modifiers.storage {
-            attributes.push(quote! { storage(#ty) });
+            let span = ty.span();
+            attributes.push(quote_spanned! {span=> storage(#ty) });
         };
         // Pass on the cycle_delay_bug modifier
-        if modifiers.cycle_delay_bug {
-            attributes.push(quote! { cycle_delay_bug });
+        if let Some(cycle_delay_bug) = &modifiers.cycle_delay_bug {
+            attributes.push(quote! { #cycle_delay_bug });
         };
         // Pass on the no_hash modifier
-        if modifiers.no_hash {
-            attributes.push(quote! { no_hash });
+        if let Some(no_hash) = &modifiers.no_hash {
+            attributes.push(quote! { #no_hash });
         };
         // Pass on the anon modifier
-        if modifiers.anon {
-            attributes.push(quote! { anon });
+        if let Some(anon) = &modifiers.anon {
+            attributes.push(quote! { #anon });
         };
         // Pass on the eval_always modifier
-        if modifiers.eval_always {
-            attributes.push(quote! { eval_always });
+        if let Some(eval_always) = &modifiers.eval_always {
+            attributes.push(quote! { #eval_always });
         };
 
-        let attribute_stream = quote! {#(#attributes),*};
+        // This uses the span of the query definition for the commas,
+        // which can be important if we later encounter any ambiguity
+        // errors with any of the numerous macro_rules! macros that
+        // we use. Using the call-site span would result in a span pointing
+        // at the entire `rustc_queries!` invocation, which wouldn't
+        // be very useful.
+        let span = name.span();
+        let attribute_stream = quote_spanned! {span=> #(#attributes),*};
         let doc_comments = query.doc_comments.iter();
         // Add the query to the group
         query_stream.extend(quote! {
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 3df8ade2169..a683cb05e16 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -11,7 +11,8 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet};
+use rustc_hir::def_id::{CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::intravisit::{self, DeepVisitor, NestedVisitorMap, Visitor};
 use rustc_hir::{AssocItemKind, HirIdSet, Node, PatKind};
 use rustc_middle::bug;
@@ -354,9 +355,8 @@ trait VisibilityLike: Sized {
 
     // Returns an over-approximation (`skip_assoc_tys` = true) of visibility due to
     // associated types for which we can't determine visibility precisely.
-    fn of_impl(hir_id: hir::HirId, tcx: TyCtxt<'_>, access_levels: &AccessLevels) -> Self {
+    fn of_impl(def_id: LocalDefId, tcx: TyCtxt<'_>, access_levels: &AccessLevels) -> Self {
         let mut find = FindMin { tcx, access_levels, min: Self::MAX };
-        let def_id = tcx.hir().local_def_id(hir_id);
         find.visit(tcx.type_of(def_id));
         if let Some(trait_ref) = tcx.impl_trait_ref(def_id) {
             find.visit_trait(trait_ref);
@@ -424,7 +424,7 @@ struct EmbargoVisitor<'tcx> {
 
 struct ReachEverythingInTheInterfaceVisitor<'a, 'tcx> {
     access_level: Option<AccessLevel>,
-    item_def_id: DefId,
+    item_def_id: LocalDefId,
     ev: &'a mut EmbargoVisitor<'tcx>,
 }
 
@@ -448,12 +448,12 @@ impl EmbargoVisitor<'tcx> {
 
     fn reach(
         &mut self,
-        item_id: hir::HirId,
+        def_id: LocalDefId,
         access_level: Option<AccessLevel>,
     ) -> ReachEverythingInTheInterfaceVisitor<'_, 'tcx> {
         ReachEverythingInTheInterfaceVisitor {
             access_level: cmp::min(access_level, Some(AccessLevel::Reachable)),
-            item_def_id: self.tcx.hir().local_def_id(item_id).to_def_id(),
+            item_def_id: def_id,
             ev: self,
         }
     }
@@ -536,10 +536,10 @@ impl EmbargoVisitor<'tcx> {
                     | hir::ItemKind::Union(ref struct_def, _) = item.kind
                     {
                         for field in struct_def.fields() {
-                            let field_vis =
-                                self.tcx.visibility(self.tcx.hir().local_def_id(field.hir_id));
+                            let def_id = self.tcx.hir().local_def_id(field.hir_id);
+                            let field_vis = self.tcx.visibility(def_id);
                             if field_vis.is_accessible_from(module.to_def_id(), self.tcx) {
-                                self.reach(field.hir_id, level).ty();
+                                self.reach(def_id, level).ty();
                             }
                         }
                     } else {
@@ -638,7 +638,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
         let inherited_item_level = match item.kind {
             hir::ItemKind::Impl { .. } => {
-                Option::<AccessLevel>::of_impl(item.hir_id(), self.tcx, &self.access_levels)
+                Option::<AccessLevel>::of_impl(item.def_id, self.tcx, &self.access_levels)
             }
             // Foreign modules inherit level from parents.
             hir::ItemKind::ForeignMod { .. } => self.prev_level,
@@ -750,7 +750,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
                     // reachable if they are returned via `impl Trait`, even from private functions.
                     let exist_level =
                         cmp::max(item_level, Some(AccessLevel::ReachableFromImplTrait));
-                    self.reach(item.hir_id(), exist_level).generics().predicates().ty();
+                    self.reach(item.def_id, exist_level).generics().predicates().ty();
                 }
             }
             // Visit everything.
@@ -759,15 +759,15 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
             | hir::ItemKind::Fn(..)
             | hir::ItemKind::TyAlias(..) => {
                 if item_level.is_some() {
-                    self.reach(item.hir_id(), item_level).generics().predicates().ty();
+                    self.reach(item.def_id, item_level).generics().predicates().ty();
                 }
             }
             hir::ItemKind::Trait(.., trait_item_refs) => {
                 if item_level.is_some() {
-                    self.reach(item.hir_id(), item_level).generics().predicates();
+                    self.reach(item.def_id, item_level).generics().predicates();
 
                     for trait_item_ref in trait_item_refs {
-                        let mut reach = self.reach(trait_item_ref.id.hir_id(), item_level);
+                        let mut reach = self.reach(trait_item_ref.id.def_id, item_level);
                         reach.generics().predicates();
 
                         if trait_item_ref.kind == AssocItemKind::Type
@@ -782,18 +782,18 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
             }
             hir::ItemKind::TraitAlias(..) => {
                 if item_level.is_some() {
-                    self.reach(item.hir_id(), item_level).generics().predicates();
+                    self.reach(item.def_id, item_level).generics().predicates();
                 }
             }
             // Visit everything except for private impl items.
             hir::ItemKind::Impl(ref impl_) => {
                 if item_level.is_some() {
-                    self.reach(item.hir_id(), item_level).generics().predicates().ty().trait_ref();
+                    self.reach(item.def_id, item_level).generics().predicates().ty().trait_ref();
 
                     for impl_item_ref in impl_.items {
                         let impl_item_level = self.get(impl_item_ref.id.def_id);
                         if impl_item_level.is_some() {
-                            self.reach(impl_item_ref.id.hir_id(), impl_item_level)
+                            self.reach(impl_item_ref.id.def_id, impl_item_level)
                                 .generics()
                                 .predicates()
                                 .ty();
@@ -805,13 +805,14 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
             // Visit everything, but enum variants have their own levels.
             hir::ItemKind::Enum(ref def, _) => {
                 if item_level.is_some() {
-                    self.reach(item.hir_id(), item_level).generics().predicates();
+                    self.reach(item.def_id, item_level).generics().predicates();
                 }
                 for variant in def.variants {
                     let variant_level = self.get(self.tcx.hir().local_def_id(variant.id));
                     if variant_level.is_some() {
                         for field in variant.data.fields() {
-                            self.reach(field.hir_id, variant_level).ty();
+                            self.reach(self.tcx.hir().local_def_id(field.hir_id), variant_level)
+                                .ty();
                         }
                         // Corner case: if the variant is reachable, but its
                         // enum is not, make the enum reachable as well.
@@ -824,7 +825,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
                 for foreign_item in items {
                     let foreign_item_level = self.get(foreign_item.id.def_id);
                     if foreign_item_level.is_some() {
-                        self.reach(foreign_item.id.hir_id(), foreign_item_level)
+                        self.reach(foreign_item.id.def_id, foreign_item_level)
                             .generics()
                             .predicates()
                             .ty();
@@ -834,11 +835,12 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
             // Visit everything except for private fields.
             hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) => {
                 if item_level.is_some() {
-                    self.reach(item.hir_id(), item_level).generics().predicates();
+                    self.reach(item.def_id, item_level).generics().predicates();
                     for field in struct_def.fields() {
-                        let field_level = self.get(self.tcx.hir().local_def_id(field.hir_id));
+                        let def_id = self.tcx.hir().local_def_id(field.hir_id);
+                        let field_level = self.get(def_id);
                         if field_level.is_some() {
-                            self.reach(field.hir_id, field_level).ty();
+                            self.reach(def_id, field_level).ty();
                         }
                     }
                 }
@@ -992,7 +994,7 @@ impl DefIdVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'tcx> {
 struct NamePrivacyVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
     maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
-    current_item: Option<hir::HirId>,
+    current_item: LocalDefId,
 }
 
 impl<'tcx> NamePrivacyVisitor<'tcx> {
@@ -1014,11 +1016,15 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
         field: &'tcx ty::FieldDef,
         in_update_syntax: bool,
     ) {
+        if def.is_enum() {
+            return;
+        }
+
         // definition of the field
         let ident = Ident::new(kw::Empty, use_ctxt);
-        let current_hir = self.current_item.unwrap();
-        let def_id = self.tcx.adjust_ident_and_get_scope(ident, def.did, current_hir).1;
-        if !def.is_enum() && !field.vis.is_accessible_from(def_id, self.tcx) {
+        let hir_id = self.tcx.hir().local_def_id_to_hir_id(self.current_item);
+        let def_id = self.tcx.adjust_ident_and_get_scope(ident, def.did, hir_id).1;
+        if !field.vis.is_accessible_from(def_id, self.tcx) {
             let label = if in_update_syntax {
                 format!("field `{}` is private", field.ident)
             } else {
@@ -1063,7 +1069,7 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
     }
 
     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
-        let orig_current_item = self.current_item.replace(item.hir_id());
+        let orig_current_item = mem::replace(&mut self.current_item, item.def_id);
         intravisit::walk_item(self, item);
         self.current_item = orig_current_item;
     }
@@ -1763,9 +1769,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
 
 struct SearchInterfaceForPrivateItemsVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
-    item_id: hir::HirId,
-    item_def_id: DefId,
-    span: Span,
+    item_def_id: LocalDefId,
     /// The visitor checks that each component type is at least this visible.
     required_visibility: ty::Visibility,
     has_pub_restricted: bool,
@@ -1820,8 +1824,8 @@ impl SearchInterfaceForPrivateItemsVisitor<'tcx> {
         if self.leaks_private_dep(def_id) {
             self.tcx.struct_span_lint_hir(
                 lint::builtin::EXPORTED_PRIVATE_DEPENDENCIES,
-                self.item_id,
-                self.span,
+                self.tcx.hir().local_def_id_to_hir_id(self.item_def_id),
+                self.tcx.def_span(self.item_def_id.to_def_id()),
                 |lint| {
                     lint.build(&format!(
                         "{} `{}` from private dependency '{}' in public \
@@ -1856,15 +1860,16 @@ impl SearchInterfaceForPrivateItemsVisitor<'tcx> {
                 }
             };
             let make_msg = || format!("{} {} `{}` in public interface", vis_descr, kind, descr);
+            let span = self.tcx.def_span(self.item_def_id.to_def_id());
             if self.has_pub_restricted || self.has_old_errors || self.in_assoc_ty {
                 let mut err = if kind == "trait" {
-                    struct_span_err!(self.tcx.sess, self.span, E0445, "{}", make_msg())
+                    struct_span_err!(self.tcx.sess, span, E0445, "{}", make_msg())
                 } else {
-                    struct_span_err!(self.tcx.sess, self.span, E0446, "{}", make_msg())
+                    struct_span_err!(self.tcx.sess, span, E0446, "{}", make_msg())
                 };
                 let vis_span =
                     self.tcx.sess.source_map().guess_head_span(self.tcx.def_span(def_id));
-                err.span_label(self.span, format!("can't leak {} {}", vis_descr, kind));
+                err.span_label(span, format!("can't leak {} {}", vis_descr, kind));
                 err.span_label(vis_span, format!("`{}` declared as {}", descr, vis_descr));
                 err.emit();
             } else {
@@ -1872,7 +1877,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'tcx> {
                 self.tcx.struct_span_lint_hir(
                     lint::builtin::PRIVATE_IN_PUBLIC,
                     hir_id,
-                    self.span,
+                    span,
                     |lint| lint.build(&format!("{} (error {})", make_msg(), err_code)).emit(),
                 );
             }
@@ -1915,35 +1920,33 @@ impl DefIdVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'tcx> {
 struct PrivateItemsInPublicInterfacesVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
     has_pub_restricted: bool,
-    old_error_set_ancestry: HirIdSet,
+    old_error_set_ancestry: LocalDefIdSet,
 }
 
 impl<'tcx> PrivateItemsInPublicInterfacesVisitor<'tcx> {
     fn check(
         &self,
-        item_id: hir::HirId,
+        def_id: LocalDefId,
         required_visibility: ty::Visibility,
     ) -> SearchInterfaceForPrivateItemsVisitor<'tcx> {
         SearchInterfaceForPrivateItemsVisitor {
             tcx: self.tcx,
-            item_id,
-            item_def_id: self.tcx.hir().local_def_id(item_id).to_def_id(),
-            span: self.tcx.hir().span(item_id),
+            item_def_id: def_id,
             required_visibility,
             has_pub_restricted: self.has_pub_restricted,
-            has_old_errors: self.old_error_set_ancestry.contains(&item_id),
+            has_old_errors: self.old_error_set_ancestry.contains(&def_id),
             in_assoc_ty: false,
         }
     }
 
     fn check_assoc_item(
         &self,
-        hir_id: hir::HirId,
+        def_id: LocalDefId,
         assoc_item_kind: AssocItemKind,
         defaultness: hir::Defaultness,
         vis: ty::Visibility,
     ) {
-        let mut check = self.check(hir_id, vis);
+        let mut check = self.check(def_id, vis);
 
         let (check_ty, is_assoc_ty) = match assoc_item_kind {
             AssocItemKind::Const | AssocItemKind::Fn { .. } => (true, false),
@@ -1982,38 +1985,38 @@ impl<'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'tcx> {
             | hir::ItemKind::Static(..)
             | hir::ItemKind::Fn(..)
             | hir::ItemKind::TyAlias(..) => {
-                self.check(item.hir_id(), item_visibility).generics().predicates().ty();
+                self.check(item.def_id, item_visibility).generics().predicates().ty();
             }
             hir::ItemKind::OpaqueTy(..) => {
                 // `ty()` for opaque types is the underlying type,
                 // it's not a part of interface, so we skip it.
-                self.check(item.hir_id(), item_visibility).generics().bounds();
+                self.check(item.def_id, item_visibility).generics().bounds();
             }
             hir::ItemKind::Trait(.., trait_item_refs) => {
-                self.check(item.hir_id(), item_visibility).generics().predicates();
+                self.check(item.def_id, item_visibility).generics().predicates();
 
                 for trait_item_ref in trait_item_refs {
                     self.check_assoc_item(
-                        trait_item_ref.id.hir_id(),
+                        trait_item_ref.id.def_id,
                         trait_item_ref.kind,
                         trait_item_ref.defaultness,
                         item_visibility,
                     );
 
                     if let AssocItemKind::Type = trait_item_ref.kind {
-                        self.check(trait_item_ref.id.hir_id(), item_visibility).bounds();
+                        self.check(trait_item_ref.id.def_id, item_visibility).bounds();
                     }
                 }
             }
             hir::ItemKind::TraitAlias(..) => {
-                self.check(item.hir_id(), item_visibility).generics().predicates();
+                self.check(item.def_id, item_visibility).generics().predicates();
             }
             hir::ItemKind::Enum(ref def, _) => {
-                self.check(item.hir_id(), item_visibility).generics().predicates();
+                self.check(item.def_id, item_visibility).generics().predicates();
 
                 for variant in def.variants {
                     for field in variant.data.fields() {
-                        self.check(field.hir_id, item_visibility).ty();
+                        self.check(self.tcx.hir().local_def_id(field.hir_id), item_visibility).ty();
                     }
                 }
             }
@@ -2021,16 +2024,17 @@ impl<'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'tcx> {
             hir::ItemKind::ForeignMod { items, .. } => {
                 for foreign_item in items {
                     let vis = tcx.visibility(foreign_item.id.def_id);
-                    self.check(foreign_item.id.hir_id(), vis).generics().predicates().ty();
+                    self.check(foreign_item.id.def_id, vis).generics().predicates().ty();
                 }
             }
             // Subitems of structs and unions have their own publicity.
             hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) => {
-                self.check(item.hir_id(), item_visibility).generics().predicates();
+                self.check(item.def_id, item_visibility).generics().predicates();
 
                 for field in struct_def.fields() {
-                    let field_visibility = tcx.visibility(tcx.hir().local_def_id(field.hir_id));
-                    self.check(field.hir_id, min(item_visibility, field_visibility, tcx)).ty();
+                    let def_id = tcx.hir().local_def_id(field.hir_id);
+                    let field_visibility = tcx.visibility(def_id);
+                    self.check(def_id, min(item_visibility, field_visibility, tcx)).ty();
                 }
             }
             // An inherent impl is public when its type is public
@@ -2038,8 +2042,8 @@ impl<'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'tcx> {
             // A trait impl is public when both its type and its trait are public
             // Subitems of trait impls have inherited publicity.
             hir::ItemKind::Impl(ref impl_) => {
-                let impl_vis = ty::Visibility::of_impl(item.hir_id(), tcx, &Default::default());
-                self.check(item.hir_id(), impl_vis).generics().predicates();
+                let impl_vis = ty::Visibility::of_impl(item.def_id, tcx, &Default::default());
+                self.check(item.def_id, impl_vis).generics().predicates();
                 for impl_item_ref in impl_.items {
                     let impl_item_vis = if impl_.of_trait.is_none() {
                         min(tcx.visibility(impl_item_ref.id.def_id), impl_vis, tcx)
@@ -2047,7 +2051,7 @@ impl<'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'tcx> {
                         impl_vis
                     };
                     self.check_assoc_item(
-                        impl_item_ref.id.hir_id(),
+                        impl_item_ref.id.def_id,
                         impl_item_ref.kind,
                         impl_item_ref.defaultness,
                         impl_item_vis,
@@ -2119,7 +2123,8 @@ fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility {
 
 fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
     // Check privacy of names not checked in previous compilation stages.
-    let mut visitor = NamePrivacyVisitor { tcx, maybe_typeck_results: None, current_item: None };
+    let mut visitor =
+        NamePrivacyVisitor { tcx, maybe_typeck_results: None, current_item: module_def_id };
     let (module, span, hir_id) = tcx.hir().get_module(module_def_id);
 
     intravisit::walk_mod(&mut visitor, module, hir_id);
@@ -2188,7 +2193,15 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
     }
 
     // Check for private types and traits in public interfaces.
-    let mut visitor =
-        PrivateItemsInPublicInterfacesVisitor { tcx, has_pub_restricted, old_error_set_ancestry };
+    let mut visitor = PrivateItemsInPublicInterfacesVisitor {
+        tcx,
+        has_pub_restricted,
+        // Only definition IDs are ever searched in `old_error_set_ancestry`,
+        // so we can filter away all non-definition IDs at this point.
+        old_error_set_ancestry: old_error_set_ancestry
+            .into_iter()
+            .filter_map(|hir_id| tcx.hir().opt_local_def_id(hir_id))
+            .collect(),
+    };
     krate.visit_all_item_likes(&mut DeepVisitor::new(&mut visitor));
 }
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 1c95cc91208..9e127577b61 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -157,7 +157,7 @@ scoped_tls::scoped_thread_local!(static SESSION_GLOBALS: SessionGlobals);
 // FIXME: We should use this enum or something like it to get rid of the
 // use of magic `/rust/1.x/...` paths across the board.
 #[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd)]
-#[derive(HashStable_Generic, Decodable)]
+#[derive(Decodable)]
 pub enum RealFileName {
     LocalPath(PathBuf),
     /// For remapped paths (namely paths into libstd that have been mapped
@@ -269,7 +269,7 @@ impl RealFileName {
 
 /// Differentiates between real files and common virtual files.
 #[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash)]
-#[derive(HashStable_Generic, Decodable, Encodable)]
+#[derive(Decodable, Encodable)]
 pub enum FileName {
     Real(RealFileName),
     /// Call to `quote!`.
diff --git a/library/std/src/net/tcp.rs b/library/std/src/net/tcp.rs
index 325acf0b979..c8eb4811f7e 100644
--- a/library/std/src/net/tcp.rs
+++ b/library/std/src/net/tcp.rs
@@ -767,17 +767,24 @@ impl TcpListener {
     /// # Examples
     ///
     /// ```no_run
-    /// use std::net::TcpListener;
+    /// use std::net::{TcpListener, TcpStream};
     ///
-    /// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
+    /// fn handle_connection(stream: TcpStream) {
+    ///    //...
+    /// }
     ///
-    /// for stream in listener.incoming() {
-    ///     match stream {
-    ///         Ok(stream) => {
-    ///             println!("new client!");
+    /// fn main() -> std::io::Result<()> {
+    ///     let listener = TcpListener::bind("127.0.0.1:80").unwrap();
+    ///
+    ///     for stream in listener.incoming() {
+    ///         match stream {
+    ///             Ok(stream) => {
+    ///                 handle_connection(stream);
+    ///             }
+    ///             Err(e) => { /* connection failed */ }
     ///         }
-    ///         Err(e) => { /* connection failed */ }
     ///     }
+    ///     Ok(())
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 3cdb1352bef..f8fc9243e14 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -65,10 +65,11 @@ fn write_header(out: &mut Buffer, class: Option<&str>, extra_content: Option<Buf
         out.push_buffer(extra);
     }
     if let Some(class) = class {
-        writeln!(out, "<pre class=\"rust {}\">", class);
+        write!(out, "<pre class=\"rust {}\">", class);
     } else {
-        writeln!(out, "<pre class=\"rust\">");
+        write!(out, "<pre class=\"rust\">");
     }
+    write!(out, "<code>");
 }
 
 /// Convert the given `src` source code into HTML by adding classes for highlighting.
@@ -101,7 +102,7 @@ fn write_code(
 }
 
 fn write_footer(out: &mut Buffer, playground_button: Option<&str>) {
-    writeln!(out, "</pre>{}</div>", playground_button.unwrap_or_default());
+    writeln!(out, "</code></pre>{}</div>", playground_button.unwrap_or_default());
 }
 
 /// How a span of text is classified. Mostly corresponds to token kinds.
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 472323daf30..7c6d7dff816 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -234,7 +234,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
                     return Some(Event::Html(
                         format!(
                             "<div class=\"example-wrap\">\
-                                 <pre class=\"language-{}\">{}</pre>\
+                                 <pre class=\"language-{}\"><code>{}</code></pre>\
                              </div>",
                             lang,
                             Escape(&text),
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index a3b01a59f27..96cc67ce97c 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -454,24 +454,25 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::
         + name.as_str().len()
         + generics_len;
 
-    w.write_str("<pre class=\"rust fn\">");
-    render_attributes_in_pre(w, it, "");
-    w.reserve(header_len);
-    write!(
-        w,
-        "{vis}{constness}{asyncness}{unsafety}{abi}fn \
-         {name}{generics}{decl}{notable_traits}{where_clause}</pre>",
-        vis = vis,
-        constness = constness,
-        asyncness = asyncness,
-        unsafety = unsafety,
-        abi = abi,
-        name = name,
-        generics = f.generics.print(cx),
-        where_clause = print_where_clause(&f.generics, cx, 0, true),
-        decl = f.decl.full_print(header_len, 0, f.header.asyncness, cx),
-        notable_traits = notable_traits_decl(&f.decl, cx),
-    );
+    wrap_item(w, "fn", |w| {
+        render_attributes_in_pre(w, it, "");
+        w.reserve(header_len);
+        write!(
+            w,
+            "{vis}{constness}{asyncness}{unsafety}{abi}fn \
+             {name}{generics}{decl}{notable_traits}{where_clause}",
+            vis = vis,
+            constness = constness,
+            asyncness = asyncness,
+            unsafety = unsafety,
+            abi = abi,
+            name = name,
+            generics = f.generics.print(cx),
+            where_clause = print_where_clause(&f.generics, cx, 0, true),
+            decl = f.decl.full_print(header_len, 0, f.header.asyncness, cx),
+            notable_traits = notable_traits_decl(&f.decl, cx),
+        );
+    });
     document(w, cx, it, None)
 }
 
@@ -487,108 +488,111 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
 
     // Output the trait definition
     wrap_into_docblock(w, |w| {
-        w.write_str("<pre class=\"rust trait\">");
-        render_attributes_in_pre(w, it, "");
-        write!(
-            w,
-            "{}{}{}trait {}{}{}",
-            it.visibility.print_with_space(it.def_id, cx),
-            t.unsafety.print_with_space(),
-            if t.is_auto { "auto " } else { "" },
-            it.name.as_ref().unwrap(),
-            t.generics.print(cx),
-            bounds
-        );
-
-        if !t.generics.where_predicates.is_empty() {
-            write!(w, "{}", print_where_clause(&t.generics, cx, 0, true));
-        } else {
-            w.write_str(" ");
-        }
+        wrap_item(w, "trait", |w| {
+            render_attributes_in_pre(w, it, "");
+            write!(
+                w,
+                "{}{}{}trait {}{}{}",
+                it.visibility.print_with_space(it.def_id, cx),
+                t.unsafety.print_with_space(),
+                if t.is_auto { "auto " } else { "" },
+                it.name.as_ref().unwrap(),
+                t.generics.print(cx),
+                bounds
+            );
 
-        if t.items.is_empty() {
-            w.write_str("{ }");
-        } else {
-            // FIXME: we should be using a derived_id for the Anchors here
-            w.write_str("{\n");
-            let mut toggle = false;
-
-            // If there are too many associated types, hide _everything_
-            if should_hide_fields(count_types) {
-                toggle = true;
-                toggle_open(
-                    w,
-                    format_args!("{} associated items", count_types + count_consts + count_methods),
-                );
-            }
-            for t in &types {
-                render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx);
-                w.write_str(";\n");
-            }
-            // If there are too many associated constants, hide everything after them
-            // We also do this if the types + consts is large because otherwise we could
-            // render a bunch of types and _then_ a bunch of consts just because both were
-            // _just_ under the limit
-            if !toggle && should_hide_fields(count_types + count_consts) {
-                toggle = true;
-                toggle_open(
-                    w,
-                    format_args!(
-                        "{} associated constant{} and {} method{}",
-                        count_consts,
-                        pluralize(count_consts),
-                        count_methods,
-                        pluralize(count_methods),
-                    ),
-                );
-            }
-            if !types.is_empty() && !consts.is_empty() {
-                w.write_str("\n");
-            }
-            for t in &consts {
-                render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx);
-                w.write_str(";\n");
-            }
-            if !toggle && should_hide_fields(count_methods) {
-                toggle = true;
-                toggle_open(w, format_args!("{} methods", count_methods));
-            }
-            if !consts.is_empty() && !required.is_empty() {
-                w.write_str("\n");
+            if !t.generics.where_predicates.is_empty() {
+                write!(w, "{}", print_where_clause(&t.generics, cx, 0, true));
+            } else {
+                w.write_str(" ");
             }
-            for (pos, m) in required.iter().enumerate() {
-                render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait, cx);
-                w.write_str(";\n");
 
-                if pos < required.len() - 1 {
-                    w.write_str("<div class=\"item-spacer\"></div>");
+            if t.items.is_empty() {
+                w.write_str("{ }");
+            } else {
+                // FIXME: we should be using a derived_id for the Anchors here
+                w.write_str("{\n");
+                let mut toggle = false;
+
+                // If there are too many associated types, hide _everything_
+                if should_hide_fields(count_types) {
+                    toggle = true;
+                    toggle_open(
+                        w,
+                        format_args!(
+                            "{} associated items",
+                            count_types + count_consts + count_methods
+                        ),
+                    );
                 }
-            }
-            if !required.is_empty() && !provided.is_empty() {
-                w.write_str("\n");
-            }
-            for (pos, m) in provided.iter().enumerate() {
-                render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait, cx);
-                match *m.kind {
-                    clean::MethodItem(ref inner, _)
-                        if !inner.generics.where_predicates.is_empty() =>
-                    {
-                        w.write_str(",\n    { ... }\n");
+                for t in &types {
+                    render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx);
+                    w.write_str(";\n");
+                }
+                // If there are too many associated constants, hide everything after them
+                // We also do this if the types + consts is large because otherwise we could
+                // render a bunch of types and _then_ a bunch of consts just because both were
+                // _just_ under the limit
+                if !toggle && should_hide_fields(count_types + count_consts) {
+                    toggle = true;
+                    toggle_open(
+                        w,
+                        format_args!(
+                            "{} associated constant{} and {} method{}",
+                            count_consts,
+                            pluralize(count_consts),
+                            count_methods,
+                            pluralize(count_methods),
+                        ),
+                    );
+                }
+                if !types.is_empty() && !consts.is_empty() {
+                    w.write_str("\n");
+                }
+                for t in &consts {
+                    render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx);
+                    w.write_str(";\n");
+                }
+                if !toggle && should_hide_fields(count_methods) {
+                    toggle = true;
+                    toggle_open(w, format_args!("{} methods", count_methods));
+                }
+                if !consts.is_empty() && !required.is_empty() {
+                    w.write_str("\n");
+                }
+                for (pos, m) in required.iter().enumerate() {
+                    render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait, cx);
+                    w.write_str(";\n");
+
+                    if pos < required.len() - 1 {
+                        w.write_str("<div class=\"item-spacer\"></div>");
                     }
-                    _ => {
-                        w.write_str(" { ... }\n");
+                }
+                if !required.is_empty() && !provided.is_empty() {
+                    w.write_str("\n");
+                }
+                for (pos, m) in provided.iter().enumerate() {
+                    render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait, cx);
+                    match *m.kind {
+                        clean::MethodItem(ref inner, _)
+                            if !inner.generics.where_predicates.is_empty() =>
+                        {
+                            w.write_str(",\n    { ... }\n");
+                        }
+                        _ => {
+                            w.write_str(" { ... }\n");
+                        }
+                    }
+                    if pos < provided.len() - 1 {
+                        w.write_str("<div class=\"item-spacer\"></div>");
                     }
                 }
-                if pos < provided.len() - 1 {
-                    w.write_str("<div class=\"item-spacer\"></div>");
+                if toggle {
+                    toggle_close(w);
                 }
+                w.write_str("}");
             }
-            if toggle {
-                toggle_close(w);
-            }
-            w.write_str("}");
-        }
-        w.write_str("</pre>")
+        });
     });
 
     // Trait documentation
@@ -811,16 +815,17 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
 }
 
 fn item_trait_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::TraitAlias) {
-    w.write_str("<pre class=\"rust trait-alias\">");
-    render_attributes_in_pre(w, it, "");
-    write!(
-        w,
-        "trait {}{}{} = {};</pre>",
-        it.name.as_ref().unwrap(),
-        t.generics.print(cx),
-        print_where_clause(&t.generics, cx, 0, true),
-        bounds(&t.bounds, true, cx)
-    );
+    wrap_item(w, "trait-alias", |w| {
+        render_attributes_in_pre(w, it, "");
+        write!(
+            w,
+            "trait {}{}{} = {};",
+            it.name.as_ref().unwrap(),
+            t.generics.print(cx),
+            print_where_clause(&t.generics, cx, 0, true),
+            bounds(&t.bounds, true, cx)
+        );
+    });
 
     document(w, cx, it, None);
 
@@ -832,16 +837,17 @@ fn item_trait_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clea
 }
 
 fn item_opaque_ty(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::OpaqueTy) {
-    w.write_str("<pre class=\"rust opaque\">");
-    render_attributes_in_pre(w, it, "");
-    write!(
-        w,
-        "type {}{}{where_clause} = impl {bounds};</pre>",
-        it.name.as_ref().unwrap(),
-        t.generics.print(cx),
-        where_clause = print_where_clause(&t.generics, cx, 0, true),
-        bounds = bounds(&t.bounds, false, cx),
-    );
+    wrap_item(w, "opaque", |w| {
+        render_attributes_in_pre(w, it, "");
+        write!(
+            w,
+            "type {}{}{where_clause} = impl {bounds};",
+            it.name.as_ref().unwrap(),
+            t.generics.print(cx),
+            where_clause = print_where_clause(&t.generics, cx, 0, true),
+            bounds = bounds(&t.bounds, false, cx),
+        );
+    });
 
     document(w, cx, it, None);
 
@@ -859,19 +865,20 @@ fn item_typedef(
     t: &clean::Typedef,
     is_associated: bool,
 ) {
-    w.write_str("<pre class=\"rust typedef\">");
-    render_attributes_in_pre(w, it, "");
-    if !is_associated {
-        write!(w, "{}", it.visibility.print_with_space(it.def_id, cx));
-    }
-    write!(
-        w,
-        "type {}{}{where_clause} = {type_};</pre>",
-        it.name.as_ref().unwrap(),
-        t.generics.print(cx),
-        where_clause = print_where_clause(&t.generics, cx, 0, true),
-        type_ = t.type_.print(cx),
-    );
+    wrap_item(w, "typedef", |w| {
+        render_attributes_in_pre(w, it, "");
+        if !is_associated {
+            write!(w, "{}", it.visibility.print_with_space(it.def_id, cx));
+        }
+        write!(
+            w,
+            "type {}{}{where_clause} = {type_};",
+            it.name.as_ref().unwrap(),
+            t.generics.print(cx),
+            where_clause = print_where_clause(&t.generics, cx, 0, true),
+            type_ = t.type_.print(cx),
+        );
+    });
 
     document(w, cx, it, None);
 
@@ -885,10 +892,10 @@ fn item_typedef(
 
 fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Union) {
     wrap_into_docblock(w, |w| {
-        w.write_str("<pre class=\"rust union\">");
-        render_attributes_in_pre(w, it, "");
-        render_union(w, it, Some(&s.generics), &s.fields, "", cx);
-        w.write_str("</pre>")
+        wrap_item(w, "union", |w| {
+            render_attributes_in_pre(w, it, "");
+            render_union(w, it, Some(&s.generics), &s.fields, "", cx);
+        });
     });
 
     document(w, cx, it, None);
@@ -934,59 +941,68 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni
 
 fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum) {
     wrap_into_docblock(w, |w| {
-        w.write_str("<pre class=\"rust enum\">");
-        render_attributes_in_pre(w, it, "");
-        write!(
-            w,
-            "{}enum {}{}{}",
-            it.visibility.print_with_space(it.def_id, cx),
-            it.name.as_ref().unwrap(),
-            e.generics.print(cx),
-            print_where_clause(&e.generics, cx, 0, true),
-        );
-        if e.variants.is_empty() && !e.variants_stripped {
-            w.write_str(" {}");
-        } else {
-            w.write_str(" {\n");
-            let count_variants = e.variants.len();
-            let toggle = should_hide_fields(count_variants);
-            if toggle {
-                toggle_open(w, format_args!("{} variants", count_variants));
-            }
-            for v in &e.variants {
-                w.write_str("    ");
-                let name = v.name.as_ref().unwrap();
-                match *v.kind {
-                    clean::VariantItem(ref var) => match var {
-                        clean::Variant::CLike => write!(w, "{}", name),
-                        clean::Variant::Tuple(ref tys) => {
-                            write!(w, "{}(", name);
-                            for (i, ty) in tys.iter().enumerate() {
-                                if i > 0 {
-                                    w.write_str(",&nbsp;")
+        wrap_item(w, "enum", |w| {
+            render_attributes_in_pre(w, it, "");
+            write!(
+                w,
+                "{}enum {}{}{}",
+                it.visibility.print_with_space(it.def_id, cx),
+                it.name.as_ref().unwrap(),
+                e.generics.print(cx),
+                print_where_clause(&e.generics, cx, 0, true),
+            );
+            if e.variants.is_empty() && !e.variants_stripped {
+                w.write_str(" {}");
+            } else {
+                w.write_str(" {\n");
+                let count_variants = e.variants.len();
+                let toggle = should_hide_fields(count_variants);
+                if toggle {
+                    toggle_open(w, format_args!("{} variants", count_variants));
+                }
+                for v in &e.variants {
+                    w.write_str("    ");
+                    let name = v.name.as_ref().unwrap();
+                    match *v.kind {
+                        clean::VariantItem(ref var) => match var {
+                            clean::Variant::CLike => write!(w, "{}", name),
+                            clean::Variant::Tuple(ref tys) => {
+                                write!(w, "{}(", name);
+                                for (i, ty) in tys.iter().enumerate() {
+                                    if i > 0 {
+                                        w.write_str(",&nbsp;")
+                                    }
+                                    write!(w, "{}", ty.print(cx));
                                 }
-                                write!(w, "{}", ty.print(cx));
+                                w.write_str(")");
                             }
-                            w.write_str(")");
-                        }
-                        clean::Variant::Struct(ref s) => {
-                            render_struct(w, v, None, s.struct_type, &s.fields, "    ", false, cx);
-                        }
-                    },
-                    _ => unreachable!(),
+                            clean::Variant::Struct(ref s) => {
+                                render_struct(
+                                    w,
+                                    v,
+                                    None,
+                                    s.struct_type,
+                                    &s.fields,
+                                    "    ",
+                                    false,
+                                    cx,
+                                );
+                            }
+                        },
+                        _ => unreachable!(),
+                    }
+                    w.write_str(",\n");
                 }
-                w.write_str(",\n");
-            }
 
-            if e.variants_stripped {
-                w.write_str("    // some variants omitted\n");
-            }
-            if toggle {
-                toggle_close(w);
+                if e.variants_stripped {
+                    w.write_str("    // some variants omitted\n");
+                }
+                if toggle {
+                    toggle_close(w);
+                }
+                w.write_str("}");
             }
-            w.write_str("}");
-        }
-        w.write_str("</pre>")
+        });
     });
 
     document(w, cx, it, None);
@@ -1090,27 +1106,27 @@ fn item_proc_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, m: &clean
     let name = it.name.as_ref().expect("proc-macros always have names");
     match m.kind {
         MacroKind::Bang => {
-            w.push_str("<pre class=\"rust macro\">");
-            write!(w, "{}!() {{ /* proc-macro */ }}", name);
-            w.push_str("</pre>");
+            wrap_item(w, "macro", |w| {
+                write!(w, "{}!() {{ /* proc-macro */ }}", name);
+            });
         }
         MacroKind::Attr => {
-            w.push_str("<pre class=\"rust attr\">");
-            write!(w, "#[{}]", name);
-            w.push_str("</pre>");
+            wrap_item(w, "attr", |w| {
+                write!(w, "#[{}]", name);
+            });
         }
         MacroKind::Derive => {
-            w.push_str("<pre class=\"rust derive\">");
-            write!(w, "#[derive({})]", name);
-            if !m.helpers.is_empty() {
-                w.push_str("\n{\n");
-                w.push_str("    // Attributes available to this derive:\n");
-                for attr in &m.helpers {
-                    writeln!(w, "    #[{}]", attr);
+            wrap_item(w, "derive", |w| {
+                write!(w, "#[derive({})]", name);
+                if !m.helpers.is_empty() {
+                    w.push_str("\n{\n");
+                    w.push_str("    // Attributes available to this derive:\n");
+                    for attr in &m.helpers {
+                        writeln!(w, "    #[{}]", attr);
+                    }
+                    w.push_str("}\n");
                 }
-                w.push_str("}\n");
-            }
-            w.push_str("</pre>");
+            });
         }
     }
     document(w, cx, it, None)
@@ -1122,49 +1138,49 @@ fn item_primitive(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) {
 }
 
 fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean::Constant) {
-    w.write_str("<pre class=\"rust const\">");
-    render_attributes_in_code(w, it);
+    wrap_item(w, "const", |w| {
+        render_attributes_in_code(w, it);
 
-    write!(
-        w,
-        "{vis}const {name}: {typ}",
-        vis = it.visibility.print_with_space(it.def_id, cx),
-        name = it.name.as_ref().unwrap(),
-        typ = c.type_.print(cx),
-    );
+        write!(
+            w,
+            "{vis}const {name}: {typ}",
+            vis = it.visibility.print_with_space(it.def_id, cx),
+            name = it.name.as_ref().unwrap(),
+            typ = c.type_.print(cx),
+        );
 
-    let value = c.value(cx.tcx());
-    let is_literal = c.is_literal(cx.tcx());
-    let expr = c.expr(cx.tcx());
-    if value.is_some() || is_literal {
-        write!(w, " = {expr};", expr = Escape(&expr));
-    } else {
-        w.write_str(";");
-    }
+        let value = c.value(cx.tcx());
+        let is_literal = c.is_literal(cx.tcx());
+        let expr = c.expr(cx.tcx());
+        if value.is_some() || is_literal {
+            write!(w, " = {expr};", expr = Escape(&expr));
+        } else {
+            w.write_str(";");
+        }
 
-    if !is_literal {
-        if let Some(value) = &value {
-            let value_lowercase = value.to_lowercase();
-            let expr_lowercase = expr.to_lowercase();
+        if !is_literal {
+            if let Some(value) = &value {
+                let value_lowercase = value.to_lowercase();
+                let expr_lowercase = expr.to_lowercase();
 
-            if value_lowercase != expr_lowercase
-                && value_lowercase.trim_end_matches("i32") != expr_lowercase
-            {
-                write!(w, " // {value}", value = Escape(value));
+                if value_lowercase != expr_lowercase
+                    && value_lowercase.trim_end_matches("i32") != expr_lowercase
+                {
+                    write!(w, " // {value}", value = Escape(value));
+                }
             }
         }
-    }
+    });
 
-    w.write_str("</pre>");
     document(w, cx, it, None)
 }
 
 fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Struct) {
     wrap_into_docblock(w, |w| {
-        w.write_str("<pre class=\"rust struct\">");
-        render_attributes_in_code(w, it);
-        render_struct(w, it, Some(&s.generics), s.struct_type, &s.fields, "", true, cx);
-        w.write_str("</pre>")
+        wrap_item(w, "struct", |w| {
+            render_attributes_in_code(w, it);
+            render_struct(w, it, Some(&s.generics), s.struct_type, &s.fields, "", true, cx);
+        });
     });
 
     document(w, cx, it, None);
@@ -1213,28 +1229,31 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St
 }
 
 fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Static) {
-    w.write_str("<pre class=\"rust static\">");
-    render_attributes_in_code(w, it);
-    write!(
-        w,
-        "{vis}static {mutability}{name}: {typ}</pre>",
-        vis = it.visibility.print_with_space(it.def_id, cx),
-        mutability = s.mutability.print_with_space(),
-        name = it.name.as_ref().unwrap(),
-        typ = s.type_.print(cx)
-    );
+    wrap_item(w, "static", |w| {
+        render_attributes_in_code(w, it);
+        write!(
+            w,
+            "{vis}static {mutability}{name}: {typ}",
+            vis = it.visibility.print_with_space(it.def_id, cx),
+            mutability = s.mutability.print_with_space(),
+            name = it.name.as_ref().unwrap(),
+            typ = s.type_.print(cx)
+        );
+    });
     document(w, cx, it, None)
 }
 
 fn item_foreign_type(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) {
-    w.write_str("<pre class=\"rust foreigntype\">extern {\n");
-    render_attributes_in_code(w, it);
-    write!(
-        w,
-        "    {}type {};\n}}</pre>",
-        it.visibility.print_with_space(it.def_id, cx),
-        it.name.as_ref().unwrap(),
-    );
+    wrap_item(w, "foreigntype", |w| {
+        w.write_str("extern {\n");
+        render_attributes_in_code(w, it);
+        write!(
+            w,
+            "    {}type {};\n}}",
+            it.visibility.print_with_space(it.def_id, cx),
+            it.name.as_ref().unwrap(),
+        );
+    });
 
     document(w, cx, it, None);
 
@@ -1321,6 +1340,15 @@ where
     w.write_str("</div>")
 }
 
+fn wrap_item<F>(w: &mut Buffer, item_name: &str, f: F)
+where
+    F: FnOnce(&mut Buffer),
+{
+    w.write_fmt(format_args!("<pre class=\"rust {}\"><code>", item_name));
+    f(w);
+    w.write_str("</code></pre>");
+}
+
 fn render_stability_since(
     w: &mut Buffer,
     item: &clean::Item,
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 0714de9d565..23ca6eeaf3b 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -249,7 +249,6 @@ code, pre, a.test-arrow, .code-header {
 }
 .docblock pre code, .docblock-short pre code {
 	padding: 0;
-	padding-right: 1ex;
 }
 pre {
 	padding: 14px;
diff --git a/src/test/incremental/const-generics/hash-tyvid-regression-1.rs b/src/test/incremental/const-generics/hash-tyvid-regression-1.rs
new file mode 100644
index 00000000000..f98ae59ddfe
--- /dev/null
+++ b/src/test/incremental/const-generics/hash-tyvid-regression-1.rs
@@ -0,0 +1,15 @@
+// revisions: cfail
+#![feature(const_generics, const_evaluatable_checked)]
+#![allow(incomplete_features)]
+// regression test for #77650
+fn c<T, const N: std::num::NonZeroUsize>()
+where
+    [T; N.get()]: Sized,
+{
+    use std::convert::TryFrom;
+    <[T; N.get()]>::try_from(())
+    //~^ error: the trait bound
+    //~^^ error: mismatched types
+}
+
+fn main() {}
diff --git a/src/test/incremental/const-generics/hash-tyvid-regression-1.stderr b/src/test/incremental/const-generics/hash-tyvid-regression-1.stderr
new file mode 100644
index 00000000000..cb8ca3abd7f
--- /dev/null
+++ b/src/test/incremental/const-generics/hash-tyvid-regression-1.stderr
@@ -0,0 +1,35 @@
+error[E0277]: the trait bound `[T; _]: From<()>` is not satisfied
+  --> $DIR/hash-tyvid-regression-1.rs:9:5
+   |
+LL |     <[T; N.get()]>::try_from(())
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<()>` is not implemented for `[T; _]`
+   |
+   = note: required because of the requirements on the impl of `Into<[T; _]>` for `()`
+   = note: required because of the requirements on the impl of `TryFrom<()>` for `[T; _]`
+note: required by `try_from`
+  --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+   |
+LL |     fn try_from(value: T) -> Result<Self, Self::Error>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/hash-tyvid-regression-1.rs:9:5
+   |
+LL |     <[T; N.get()]>::try_from(())
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found enum `Result`
+   |
+   = note: expected unit type `()`
+                   found enum `Result<[T; _], Infallible>`
+help: consider using a semicolon here
+   |
+LL |     <[T; N.get()]>::try_from(());
+   |                                 +
+help: try adding a return type
+   |
+LL | -> Result<[T; _], Infallible> where
+   | +++++++++++++++++++++++++++++
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/incremental/const-generics/hash-tyvid-regression-2.rs b/src/test/incremental/const-generics/hash-tyvid-regression-2.rs
new file mode 100644
index 00000000000..22536ff56d7
--- /dev/null
+++ b/src/test/incremental/const-generics/hash-tyvid-regression-2.rs
@@ -0,0 +1,18 @@
+// revisions: cfail
+#![feature(const_generics, const_evaluatable_checked)]
+#![allow(incomplete_features)]
+// regression test for #77650
+struct C<T, const N: core::num::NonZeroUsize>([T; N.get()])
+where
+    [T; N.get()]: Sized;
+impl<'a, const N: core::num::NonZeroUsize, A, B: PartialEq<A>> PartialEq<&'a [A]> for C<B, N>
+where
+    [B; N.get()]: Sized,
+{
+    fn eq(&self, other: &&'a [A]) -> bool {
+        self.0 == other
+        //~^ error: can't compare
+    }
+}
+
+fn main() {}
diff --git a/src/test/incremental/const-generics/hash-tyvid-regression-2.stderr b/src/test/incremental/const-generics/hash-tyvid-regression-2.stderr
new file mode 100644
index 00000000000..0e6040ef02e
--- /dev/null
+++ b/src/test/incremental/const-generics/hash-tyvid-regression-2.stderr
@@ -0,0 +1,11 @@
+error[E0277]: can't compare `[B; _]` with `&&[A]`
+  --> $DIR/hash-tyvid-regression-2.rs:12:16
+   |
+LL |         self.0 == other
+   |                ^^ no implementation for `[B; _] == &&[A]`
+   |
+   = help: the trait `PartialEq<&&[A]>` is not implemented for `[B; _]`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/incremental/const-generics/hash-tyvid-regression-3.rs b/src/test/incremental/const-generics/hash-tyvid-regression-3.rs
new file mode 100644
index 00000000000..76b1ae11c7d
--- /dev/null
+++ b/src/test/incremental/const-generics/hash-tyvid-regression-3.rs
@@ -0,0 +1,26 @@
+// revisions: cfail
+#![feature(const_generics, const_evaluatable_checked)]
+#![allow(incomplete_features)]
+// regression test for #79251
+struct Node<const D: usize>
+where
+    SmallVec<{ D * 2 }>: ,
+{
+    keys: SmallVec<{ D * 2 }>,
+}
+
+impl<const D: usize> Node<D>
+where
+    SmallVec<{ D * 2 }>: ,
+{
+    fn new() -> Self {
+        let mut node = Node::new();
+        node.keys.some_function();
+        //~^ error: no method named
+        node
+    }
+}
+
+struct SmallVec<const D: usize> {}
+
+fn main() {}
diff --git a/src/test/incremental/const-generics/hash-tyvid-regression-3.stderr b/src/test/incremental/const-generics/hash-tyvid-regression-3.stderr
new file mode 100644
index 00000000000..555d46756dc
--- /dev/null
+++ b/src/test/incremental/const-generics/hash-tyvid-regression-3.stderr
@@ -0,0 +1,12 @@
+error[E0599]: no method named `some_function` found for struct `SmallVec` in the current scope
+  --> $DIR/hash-tyvid-regression-3.rs:17:19
+   |
+LL |         node.keys.some_function();
+   |                   ^^^^^^^^^^^^^ method not found in `SmallVec<{ D * 2 }>`
+...
+LL | struct SmallVec<const D: usize> {}
+   | ------------------------------- method `some_function` not found for this
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/incremental/const-generics/hash-tyvid-regression-4.rs b/src/test/incremental/const-generics/hash-tyvid-regression-4.rs
new file mode 100644
index 00000000000..35a675a2ab4
--- /dev/null
+++ b/src/test/incremental/const-generics/hash-tyvid-regression-4.rs
@@ -0,0 +1,40 @@
+// revisions: cfail
+#![feature(const_generics, const_evaluatable_checked)]
+#![allow(incomplete_features)]
+// regression test for #79251
+#[derive(Debug)]
+struct Node<K, const D: usize>
+where
+    SmallVec<K, { D * 2 }>: ,
+{
+    keys: SmallVec<K, { D * 2 }>,
+}
+
+impl<K, const D: usize> Node<K, D>
+where
+    SmallVec<K, { D * 2 }>: ,
+{
+    fn new() -> Self {
+        panic!()
+    }
+
+    #[inline(never)]
+    fn split(&mut self, i: usize, k: K, right: bool) -> Node<K, D> {
+        let mut node = Node::new();
+        node.keys.push(k);
+        //~^ error: no method named
+        node
+    }
+}
+
+#[derive(Debug)]
+struct SmallVec<T, const D: usize> {
+    data: [T; D],
+}
+impl<T, const D: usize> SmallVec<T, D> {
+    fn new() -> Self {
+        panic!()
+    }
+}
+
+fn main() {}
diff --git a/src/test/incremental/const-generics/hash-tyvid-regression-4.stderr b/src/test/incremental/const-generics/hash-tyvid-regression-4.stderr
new file mode 100644
index 00000000000..c9a6715e571
--- /dev/null
+++ b/src/test/incremental/const-generics/hash-tyvid-regression-4.stderr
@@ -0,0 +1,12 @@
+error[E0599]: no method named `push` found for struct `SmallVec` in the current scope
+  --> $DIR/hash-tyvid-regression-4.rs:23:19
+   |
+LL |         node.keys.push(k);
+   |                   ^^^^ method not found in `SmallVec<_, { D * 2 }>`
+...
+LL | struct SmallVec<T, const D: usize> {
+   | ---------------------------------- method `push` not found for this
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/rustdoc-gui/code-tags.goml b/src/test/rustdoc-gui/code-tags.goml
new file mode 100644
index 00000000000..200569a28d4
--- /dev/null
+++ b/src/test/rustdoc-gui/code-tags.goml
@@ -0,0 +1,20 @@
+// This test ensures that items and documentation code blocks are wrapped in <pre><code>
+goto: file://|DOC_PATH|/test_docs/fn.foo.html
+size: (1080, 600)
+// There should be three doc codeblocks
+// Check that their content is inside <pre><code>
+assert-count: (".example-wrap pre > code", 3)
+// Check that function signature is inside <pre><code>
+assert: "pre.rust.fn > code"
+
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+assert: "pre.rust.struct > code"
+
+goto: file://|DOC_PATH|/test_docs/enum.AnEnum.html
+assert: "pre.rust.enum > code"
+
+goto: file://|DOC_PATH|/test_docs/trait.AnotherOne.html
+assert: "pre.rust.trait > code"
+
+goto: file://|DOC_PATH|/test_docs/type.SomeType.html
+assert: "pre.rust.typedef > code"
diff --git a/src/test/rustdoc-gui/source-code-page.goml b/src/test/rustdoc-gui/source-code-page.goml
index d7bae93c211..5a49807e180 100644
--- a/src/test/rustdoc-gui/source-code-page.goml
+++ b/src/test/rustdoc-gui/source-code-page.goml
@@ -12,4 +12,4 @@ assert-attribute: (".line-numbers > span:nth-child(5)", {"class": "line-highligh
 assert-attribute: (".line-numbers > span:nth-child(6)", {"class": "line-highlighted"})
 assert-attribute-false: (".line-numbers > span:nth-child(7)", {"class": "line-highlighted"})
 // This is to ensure that the content is correctly align with the line numbers.
-compare-elements-position: ("//*[@id='1']", ".rust > span", ("y"))
+compare-elements-position: ("//*[@id='1']", ".rust > code > span", ("y"))
diff --git a/src/test/ui/type-alias-impl-trait/unused_generic_param.rs b/src/test/ui/type-alias-impl-trait/unused_generic_param.rs
index 04a5c58cd36..ad5e4918cca 100644
--- a/src/test/ui/type-alias-impl-trait/unused_generic_param.rs
+++ b/src/test/ui/type-alias-impl-trait/unused_generic_param.rs
@@ -1,16 +1,17 @@
+// check-pass
+
 #![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
 
 fn main() {}
 
-type PartiallyDefined<T> = impl 'static;
-//~^ ERROR: at least one trait must be specified
+type PartiallyDefined<T> = impl Sized;
 
 fn partially_defined<T: std::fmt::Debug>(_: T) -> PartiallyDefined<T> {
     4u32
 }
 
-type PartiallyDefined2<T> = impl 'static;
-//~^ ERROR: at least one trait must be specified
+type PartiallyDefined2<T> = impl Sized;
 
 fn partially_defined2<T: std::fmt::Debug>(_: T) -> PartiallyDefined2<T> {
     4u32
diff --git a/src/test/ui/type-alias-impl-trait/unused_generic_param.stderr b/src/test/ui/type-alias-impl-trait/unused_generic_param.stderr
deleted file mode 100644
index 4e11854b071..00000000000
--- a/src/test/ui/type-alias-impl-trait/unused_generic_param.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error: at least one trait must be specified
-  --> $DIR/unused_generic_param.rs:5:28
-   |
-LL | type PartiallyDefined<T> = impl 'static;
-   |                            ^^^^^^^^^^^^
-
-error: at least one trait must be specified
-  --> $DIR/unused_generic_param.rs:12:29
-   |
-LL | type PartiallyDefined2<T> = impl 'static;
-   |                             ^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
-