Skip to content

Commit e8869cb

Browse files
Wrap the span_map tuple index into a type called "LightSpan"
1 parent c5c927d commit e8869cb

File tree

4 files changed

+68
-44
lines changed

4 files changed

+68
-44
lines changed

src/librustdoc/html/highlight.rs

Lines changed: 10 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_span::edition::Edition;
1717
use rustc_span::symbol::Symbol;
1818

1919
use super::format::{self, Buffer};
20-
use super::render::LinkFromSrc;
20+
use super::render::{LightSpan, LinkFromSrc};
2121

2222
/// Highlights `src`, returning the HTML output.
2323
crate fn render_with_highlighting(
@@ -74,7 +74,7 @@ fn write_header(out: &mut Buffer, class: Option<&str>, extra_content: Option<Buf
7474
/// won't try to generate links to an ident definition.
7575
///
7676
/// More explanations about spans and how we use them here are provided in the
77-
/// [`local_span_to_global_span`] function documentation about how it works.
77+
/// [`LightSpan::new_in_file`] function documentation about how it works.
7878
///
7979
/// As for `root_path`, it's used to know "how far" from the top of the directory we are to link
8080
/// to either documentation pages or other source pages.
@@ -115,14 +115,14 @@ enum Class {
115115
KeyWord,
116116
// Keywords that do pointer/reference stuff.
117117
RefKeyWord,
118-
Self_((u32, u32)),
118+
Self_(LightSpan),
119119
Op,
120120
Macro,
121121
MacroNonTerminal,
122122
String,
123123
Number,
124124
Bool,
125-
Ident((u32, u32)),
125+
Ident(LightSpan),
126126
Lifetime,
127127
PreludeTy,
128128
PreludeVal,
@@ -155,7 +155,7 @@ impl Class {
155155

156156
/// In case this is an item which can be converted into a link to a definition, it'll contain
157157
/// a "span" (a tuple representing `(lo, hi)` equivalent of `Span`).
158-
fn get_span(self) -> Option<(u32, u32)> {
158+
fn get_span(self) -> Option<LightSpan> {
159159
match self {
160160
Self::Ident(sp) | Self::Self_(sp) => Some(sp),
161161
_ => None,
@@ -201,23 +201,6 @@ fn get_real_ident_class(text: &str, edition: Edition, allow_path_keywords: bool)
201201
})
202202
}
203203

204-
/// Before explaining what this function does, some global explanations on rust's `Span`:
205-
///
206-
/// Each source code file is stored in the source map in the compiler and has a
207-
/// `lo` and a `hi` (lowest and highest bytes in this source map which can be seen as one huge
208-
/// string to simplify things). So in this case, this represents the starting byte of the current
209-
/// file. It'll be used later on to retrieve the "definition span" from the
210-
/// `span_correspondance_map` (which is inside `context`).
211-
///
212-
/// This when we transform the "span" we have from reading the input into a "span" which can be
213-
/// used as index to the `span_correspondance_map` to get the definition of this item.
214-
///
215-
/// So in here, `file_span_lo` is representing the "lo" byte in the global source map, and to make
216-
/// our "span" works in there, we simply add `file_span_lo` to our values.
217-
fn local_span_to_global_span(file_span_lo: u32, start: u32, end: u32) -> (u32, u32) {
218-
(start + file_span_lo, end + file_span_lo)
219-
}
220-
221204
/// Processes program tokens, classifying strings of text by highlighting
222205
/// category (`Class`).
223206
struct Classifier<'a> {
@@ -234,7 +217,7 @@ struct Classifier<'a> {
234217
impl<'a> Classifier<'a> {
235218
/// Takes as argument the source code to HTML-ify, the rust edition to use and the source code
236219
/// file "lo" byte which we be used later on by the `span_correspondance_map`. More explanations
237-
/// are provided in the [`local_span_to_global_span`] function documentation about how it works.
220+
/// are provided in the [`LightSpan::new_in_file`] function documentation about how it works.
238221
fn new(src: &str, edition: Edition, file_span_lo: u32) -> Classifier<'_> {
239222
let tokens = TokenIter { src }.peekable();
240223
Classifier {
@@ -496,20 +479,20 @@ impl<'a> Classifier<'a> {
496479
self.in_macro_nonterminal = false;
497480
Class::MacroNonTerminal
498481
}
499-
"self" | "Self" => Class::Self_(local_span_to_global_span(
482+
"self" | "Self" => Class::Self_(LightSpan::new_in_file(
500483
self.file_span_lo,
501484
before,
502485
before + text.len() as u32,
503486
)),
504-
_ => Class::Ident(local_span_to_global_span(
487+
_ => Class::Ident(LightSpan::new_in_file(
505488
self.file_span_lo,
506489
before,
507490
before + text.len() as u32,
508491
)),
509492
},
510493
Some(c) => c,
511494
},
512-
TokenKind::RawIdent | TokenKind::UnknownPrefix => Class::Ident(local_span_to_global_span(
495+
TokenKind::RawIdent | TokenKind::UnknownPrefix => Class::Ident(LightSpan::new_in_file(
513496
self.file_span_lo,
514497
before,
515498
before + text.len() as u32,
@@ -572,7 +555,7 @@ fn string<T: Display>(
572555
"self" | "Self" => write!(
573556
&mut path,
574557
"<span class=\"{}\">{}</span>",
575-
Class::Self_((0, 0)).as_html(),
558+
Class::Self_(LightSpan::empty()).as_html(),
576559
t
577560
),
578561
"crate" | "super" => write!(

src/librustdoc/html/render/context.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ use super::cache::{build_index, ExternalLocation};
1818
use super::print_item::{full_path, item_path, print_item};
1919
use super::write_shared::write_shared;
2020
use super::{
21-
collect_spans_and_sources, print_sidebar, settings, AllTypes, LinkFromSrc, NameDoc, StylePath,
22-
BASIC_KEYWORDS,
21+
collect_spans_and_sources, print_sidebar, settings, AllTypes, LightSpan, LinkFromSrc, NameDoc,
22+
StylePath, BASIC_KEYWORDS,
2323
};
2424

2525
use crate::clean;
@@ -131,7 +131,7 @@ crate struct SharedContext<'tcx> {
131131

132132
/// Correspondance map used to link types used in the source code pages to allow to click on
133133
/// links to jump to the type's definition.
134-
crate span_correspondance_map: FxHashMap<(u32, u32), LinkFromSrc>,
134+
crate span_correspondance_map: FxHashMap<LightSpan, LinkFromSrc>,
135135
}
136136

137137
impl SharedContext<'_> {

src/librustdoc/html/render/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ mod span_map;
3434
mod write_shared;
3535

3636
crate use context::*;
37-
crate use span_map::{collect_spans_and_sources, LinkFromSrc};
37+
crate use span_map::{collect_spans_and_sources, LightSpan, LinkFromSrc};
3838

3939
use std::collections::VecDeque;
4040
use std::default::Default;

src/librustdoc/html/render/span_map.rs

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,43 @@ crate enum LinkFromSrc {
2424
External(DefId),
2525
}
2626

27+
/// This struct is used only as index in the `span_map`, not as [`Span`]! `Span`s contain
28+
/// some extra information (the syntax context) we don't need. **Do not convert this type back to
29+
/// `Span`!!!**
30+
#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
31+
crate struct LightSpan {
32+
crate lo: u32,
33+
crate hi: u32,
34+
}
35+
36+
impl LightSpan {
37+
/// Before explaining what this method does, some global explanations on rust's `Span`:
38+
///
39+
/// Each source code file is stored in the source map in the compiler and has a
40+
/// `lo` and a `hi` (lowest and highest bytes in this source map which can be seen as one huge
41+
/// string to simplify things). So in this case, this represents the starting byte of the
42+
/// current file. It'll be used later on to retrieve the "definition span" from the
43+
/// `span_correspondance_map` (which is inside `context`).
44+
///
45+
/// This when we transform the "span" we have from reading the input into a "span" which can be
46+
/// used as index to the `span_correspondance_map` to get the definition of this item.
47+
///
48+
/// So in here, `file_span_lo` is representing the "lo" byte in the global source map, and to
49+
/// make our "span" works in there, we simply add `file_span_lo` to our values.
50+
crate fn new_in_file(file_span_lo: u32, lo: u32, hi: u32) -> Self {
51+
Self { lo: lo + file_span_lo, hi: hi + file_span_lo }
52+
}
53+
54+
crate fn empty() -> Self {
55+
Self { lo: 0, hi: 0 }
56+
}
57+
58+
/// Extra the `lo` and `hi` from the [`Span`] and discard the unused syntax context.
59+
fn new_from_span(sp: Span) -> Self {
60+
Self { lo: sp.lo().0, hi: sp.hi().0 }
61+
}
62+
}
63+
2764
/// This function will do at most two things:
2865
///
2966
/// 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(
4077
src_root: &Path,
4178
include_sources: bool,
4279
generate_link_to_definition: bool,
43-
) -> (clean::Crate, FxHashMap<PathBuf, String>, FxHashMap<(u32, u32), LinkFromSrc>) {
80+
) -> (clean::Crate, FxHashMap<PathBuf, String>, FxHashMap<LightSpan, LinkFromSrc>) {
4481
let mut visitor = SpanMapVisitor { tcx, matches: FxHashMap::default() };
4582

4683
if include_sources {
@@ -54,13 +91,9 @@ crate fn collect_spans_and_sources(
5491
}
5592
}
5693

57-
fn span_to_tuple(span: Span) -> (u32, u32) {
58-
(span.lo().0, span.hi().0)
59-
}
60-
6194
struct SpanMapVisitor<'tcx> {
6295
crate tcx: TyCtxt<'tcx>,
63-
crate matches: FxHashMap<(u32, u32), LinkFromSrc>,
96+
crate matches: FxHashMap<LightSpan, LinkFromSrc>,
6497
}
6598

6699
impl<'tcx> SpanMapVisitor<'tcx> {
@@ -77,12 +110,16 @@ impl<'tcx> SpanMapVisitor<'tcx> {
77110
};
78111
if let Some(span) = self.tcx.hir().res_span(path.res) {
79112
self.matches.insert(
80-
path_span.map(span_to_tuple).unwrap_or_else(|| span_to_tuple(path.span)),
113+
path_span
114+
.map(LightSpan::new_from_span)
115+
.unwrap_or_else(|| LightSpan::new_from_span(path.span)),
81116
LinkFromSrc::Local(span),
82117
);
83118
} else if let Some(def_id) = info {
84119
self.matches.insert(
85-
path_span.map(span_to_tuple).unwrap_or_else(|| span_to_tuple(path.span)),
120+
path_span
121+
.map(LightSpan::new_from_span)
122+
.unwrap_or_else(|| LightSpan::new_from_span(path.span)),
86123
LinkFromSrc::External(def_id),
87124
);
88125
}
@@ -122,8 +159,10 @@ impl Visitor<'tcx> for SpanMapVisitor<'tcx> {
122159
if let Some(node) = self.tcx.hir().find(id) {
123160
match node {
124161
Node::Item(item) => {
125-
self.matches
126-
.insert(span_to_tuple(item.ident.span), LinkFromSrc::Local(m.inner));
162+
self.matches.insert(
163+
LightSpan::new_from_span(item.ident.span),
164+
LinkFromSrc::Local(m.inner),
165+
);
127166
}
128167
_ => {}
129168
}
@@ -146,12 +185,14 @@ impl Visitor<'tcx> for SpanMapVisitor<'tcx> {
146185
if let Some(def_id) = typeck_results.type_dependent_def_id(expr.hir_id) {
147186
match hir.span_if_local(def_id) {
148187
Some(span) => {
149-
self.matches
150-
.insert(span_to_tuple(method_span), LinkFromSrc::Local(span));
188+
self.matches.insert(
189+
LightSpan::new_from_span(method_span),
190+
LinkFromSrc::Local(span),
191+
);
151192
}
152193
None => {
153194
self.matches.insert(
154-
span_to_tuple(method_span),
195+
LightSpan::new_from_span(method_span),
155196
LinkFromSrc::External(def_id),
156197
);
157198
}

0 commit comments

Comments
 (0)