about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustdoc/html/highlight.rs37
-rw-r--r--src/librustdoc/html/render/context.rs6
-rw-r--r--src/librustdoc/html/render/mod.rs2
-rw-r--r--src/librustdoc/html/render/span_map.rs67
4 files changed, 68 insertions, 44 deletions
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index edbb5dba1f3..808e1ca236f 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -17,7 +17,7 @@ use rustc_span::edition::Edition;
 use rustc_span::symbol::Symbol;
 
 use super::format::{self, Buffer};
-use super::render::LinkFromSrc;
+use super::render::{LightSpan, LinkFromSrc};
 
 /// Highlights `src`, returning the HTML output.
 crate fn render_with_highlighting(
@@ -74,7 +74,7 @@ fn write_header(out: &mut Buffer, class: Option<&str>, extra_content: Option<Buf
 /// won't try to generate links to an ident definition.
 ///
 /// More explanations about spans and how we use them here are provided in the
-/// [`local_span_to_global_span`] function documentation about how it works.
+/// [`LightSpan::new_in_file`] function documentation about how it works.
 ///
 /// As for `root_path`, it's used to know "how far" from the top of the directory we are to link
 /// to either documentation pages or other source pages.
@@ -115,14 +115,14 @@ enum Class {
     KeyWord,
     // Keywords that do pointer/reference stuff.
     RefKeyWord,
-    Self_((u32, u32)),
+    Self_(LightSpan),
     Op,
     Macro,
     MacroNonTerminal,
     String,
     Number,
     Bool,
-    Ident((u32, u32)),
+    Ident(LightSpan),
     Lifetime,
     PreludeTy,
     PreludeVal,
@@ -155,7 +155,7 @@ impl Class {
 
     /// In case this is an item which can be converted into a link to a definition, it'll contain
     /// a "span" (a tuple representing `(lo, hi)` equivalent of `Span`).
-    fn get_span(self) -> Option<(u32, u32)> {
+    fn get_span(self) -> Option<LightSpan> {
         match self {
             Self::Ident(sp) | Self::Self_(sp) => Some(sp),
             _ => None,
@@ -201,23 +201,6 @@ fn get_real_ident_class(text: &str, edition: Edition, allow_path_keywords: bool)
     })
 }
 
-/// Before explaining what this function does, some global explanations on rust's `Span`:
-///
-/// Each source code file is stored in the source map in the compiler and has a
-/// `lo` and a `hi` (lowest and highest bytes in this source map which can be seen as one huge
-/// string to simplify things). So in this case, this represents the starting byte of the current
-/// file. It'll be used later on to retrieve the "definition span" from the
-/// `span_correspondance_map` (which is inside `context`).
-///
-/// This when we transform the "span" we have from reading the input into a "span" which can be
-/// used as index to the `span_correspondance_map` to get the definition of this item.
-///
-/// So in here, `file_span_lo` is representing the "lo" byte in the global source map, and to make
-/// our "span" works in there, we simply add `file_span_lo` to our values.
-fn local_span_to_global_span(file_span_lo: u32, start: u32, end: u32) -> (u32, u32) {
-    (start + file_span_lo, end + file_span_lo)
-}
-
 /// Processes program tokens, classifying strings of text by highlighting
 /// category (`Class`).
 struct Classifier<'a> {
@@ -234,7 +217,7 @@ struct Classifier<'a> {
 impl<'a> Classifier<'a> {
     /// Takes as argument the source code to HTML-ify, the rust edition to use and the source code
     /// file "lo" byte which we be used later on by the `span_correspondance_map`. More explanations
-    /// are provided in the [`local_span_to_global_span`] function documentation about how it works.
+    /// are provided in the [`LightSpan::new_in_file`] function documentation about how it works.
     fn new(src: &str, edition: Edition, file_span_lo: u32) -> Classifier<'_> {
         let tokens = TokenIter { src }.peekable();
         Classifier {
@@ -496,12 +479,12 @@ impl<'a> Classifier<'a> {
                         self.in_macro_nonterminal = false;
                         Class::MacroNonTerminal
                     }
-                    "self" | "Self" => Class::Self_(local_span_to_global_span(
+                    "self" | "Self" => Class::Self_(LightSpan::new_in_file(
                         self.file_span_lo,
                         before,
                         before + text.len() as u32,
                     )),
-                    _ => Class::Ident(local_span_to_global_span(
+                    _ => Class::Ident(LightSpan::new_in_file(
                         self.file_span_lo,
                         before,
                         before + text.len() as u32,
@@ -509,7 +492,7 @@ impl<'a> Classifier<'a> {
                 },
                 Some(c) => c,
             },
-            TokenKind::RawIdent | TokenKind::UnknownPrefix => Class::Ident(local_span_to_global_span(
+            TokenKind::RawIdent | TokenKind::UnknownPrefix => Class::Ident(LightSpan::new_in_file(
                 self.file_span_lo,
                 before,
                 before + text.len() as u32,
@@ -572,7 +555,7 @@ fn string<T: Display>(
                     "self" | "Self" => write!(
                         &mut path,
                         "<span class=\"{}\">{}</span>",
-                        Class::Self_((0, 0)).as_html(),
+                        Class::Self_(LightSpan::empty()).as_html(),
                         t
                     ),
                     "crate" | "super" => write!(
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index c0668fcce99..36ec2cf3f7a 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -18,8 +18,8 @@ use super::cache::{build_index, ExternalLocation};
 use super::print_item::{full_path, item_path, print_item};
 use super::write_shared::write_shared;
 use super::{
-    collect_spans_and_sources, print_sidebar, settings, AllTypes, LinkFromSrc, NameDoc, StylePath,
-    BASIC_KEYWORDS,
+    collect_spans_and_sources, print_sidebar, settings, AllTypes, LightSpan, LinkFromSrc, NameDoc,
+    StylePath, BASIC_KEYWORDS,
 };
 
 use crate::clean;
@@ -131,7 +131,7 @@ crate struct SharedContext<'tcx> {
 
     /// Correspondance map used to link types used in the source code pages to allow to click on
     /// links to jump to the type's definition.
-    crate span_correspondance_map: FxHashMap<(u32, u32), LinkFromSrc>,
+    crate span_correspondance_map: FxHashMap<LightSpan, LinkFromSrc>,
 }
 
 impl SharedContext<'_> {
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index fd2e18a8be7..584afdeb280 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -34,7 +34,7 @@ mod span_map;
 mod write_shared;
 
 crate use context::*;
-crate use span_map::{collect_spans_and_sources, LinkFromSrc};
+crate use span_map::{collect_spans_and_sources, LightSpan, LinkFromSrc};
 
 use std::collections::VecDeque;
 use std::default::Default;
diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs
index 9990d6f0ce6..c7cc2250c24 100644
--- a/src/librustdoc/html/render/span_map.rs
+++ b/src/librustdoc/html/render/span_map.rs
@@ -24,6 +24,43 @@ crate enum LinkFromSrc {
     External(DefId),
 }
 
+/// This struct is used only as index in the `span_map`, not as [`Span`]! `Span`s contain
+/// some extra information (the syntax context) we don't need. **Do not convert this type back to
+/// `Span`!!!**
+#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
+crate struct LightSpan {
+    crate lo: u32,
+    crate hi: u32,
+}
+
+impl LightSpan {
+    /// Before explaining what this method does, some global explanations on rust's `Span`:
+    ///
+    /// Each source code file is stored in the source map in the compiler and has a
+    /// `lo` and a `hi` (lowest and highest bytes in this source map which can be seen as one huge
+    /// string to simplify things). So in this case, this represents the starting byte of the
+    /// current file. It'll be used later on to retrieve the "definition span" from the
+    /// `span_correspondance_map` (which is inside `context`).
+    ///
+    /// This when we transform the "span" we have from reading the input into a "span" which can be
+    /// used as index to the `span_correspondance_map` to get the definition of this item.
+    ///
+    /// So in here, `file_span_lo` is representing the "lo" byte in the global source map, and to
+    /// make our "span" works in there, we simply add `file_span_lo` to our values.
+    crate fn new_in_file(file_span_lo: u32, lo: u32, hi: u32) -> Self {
+        Self { lo: lo + file_span_lo, hi: hi + file_span_lo }
+    }
+
+    crate fn empty() -> Self {
+        Self { lo: 0, hi: 0 }
+    }
+
+    /// Extra the `lo` and `hi` from the [`Span`] and discard the unused syntax context.
+    fn new_from_span(sp: Span) -> Self {
+        Self { lo: sp.lo().0, hi: sp.hi().0 }
+    }
+}
+
 /// This function will do at most two things:
 ///
 /// 1. Generate a `span` correspondance map which links an item `span` to its definition `span`.
@@ -40,7 +77,7 @@ crate fn collect_spans_and_sources(
     src_root: &Path,
     include_sources: bool,
     generate_link_to_definition: bool,
-) -> (clean::Crate, FxHashMap<PathBuf, String>, FxHashMap<(u32, u32), LinkFromSrc>) {
+) -> (clean::Crate, FxHashMap<PathBuf, String>, FxHashMap<LightSpan, LinkFromSrc>) {
     let mut visitor = SpanMapVisitor { tcx, matches: FxHashMap::default() };
 
     if include_sources {
@@ -54,13 +91,9 @@ crate fn collect_spans_and_sources(
     }
 }
 
-fn span_to_tuple(span: Span) -> (u32, u32) {
-    (span.lo().0, span.hi().0)
-}
-
 struct SpanMapVisitor<'tcx> {
     crate tcx: TyCtxt<'tcx>,
-    crate matches: FxHashMap<(u32, u32), LinkFromSrc>,
+    crate matches: FxHashMap<LightSpan, LinkFromSrc>,
 }
 
 impl<'tcx> SpanMapVisitor<'tcx> {
@@ -77,12 +110,16 @@ impl<'tcx> SpanMapVisitor<'tcx> {
         };
         if let Some(span) = self.tcx.hir().res_span(path.res) {
             self.matches.insert(
-                path_span.map(span_to_tuple).unwrap_or_else(|| span_to_tuple(path.span)),
+                path_span
+                    .map(LightSpan::new_from_span)
+                    .unwrap_or_else(|| LightSpan::new_from_span(path.span)),
                 LinkFromSrc::Local(span),
             );
         } else if let Some(def_id) = info {
             self.matches.insert(
-                path_span.map(span_to_tuple).unwrap_or_else(|| span_to_tuple(path.span)),
+                path_span
+                    .map(LightSpan::new_from_span)
+                    .unwrap_or_else(|| LightSpan::new_from_span(path.span)),
                 LinkFromSrc::External(def_id),
             );
         }
@@ -122,8 +159,10 @@ impl Visitor<'tcx> for SpanMapVisitor<'tcx> {
             if let Some(node) = self.tcx.hir().find(id) {
                 match node {
                     Node::Item(item) => {
-                        self.matches
-                            .insert(span_to_tuple(item.ident.span), LinkFromSrc::Local(m.inner));
+                        self.matches.insert(
+                            LightSpan::new_from_span(item.ident.span),
+                            LinkFromSrc::Local(m.inner),
+                        );
                     }
                     _ => {}
                 }
@@ -146,12 +185,14 @@ impl Visitor<'tcx> for SpanMapVisitor<'tcx> {
                     if let Some(def_id) = typeck_results.type_dependent_def_id(expr.hir_id) {
                         match hir.span_if_local(def_id) {
                             Some(span) => {
-                                self.matches
-                                    .insert(span_to_tuple(method_span), LinkFromSrc::Local(span));
+                                self.matches.insert(
+                                    LightSpan::new_from_span(method_span),
+                                    LinkFromSrc::Local(span),
+                                );
                             }
                             None => {
                                 self.matches.insert(
-                                    span_to_tuple(method_span),
+                                    LightSpan::new_from_span(method_span),
                                     LinkFromSrc::External(def_id),
                                 );
                             }