Skip to content

Commit dfe4fec

Browse files
Remove LightSpan and use Span directly
1 parent 5cf300d commit dfe4fec

File tree

5 files changed

+44
-98
lines changed

5 files changed

+44
-98
lines changed

src/librustdoc/html/highlight.rs

+21-28
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,16 @@ use std::iter::Peekable;
1414
use rustc_lexer::{LiteralKind, TokenKind};
1515
use rustc_span::edition::Edition;
1616
use rustc_span::symbol::Symbol;
17+
use rustc_span::{BytePos, Span, DUMMY_SP};
1718

1819
use super::format::{self, Buffer};
19-
use super::render::{LightSpan, LinkFromSrc};
20+
use super::render::LinkFromSrc;
2021

2122
/// This type is needed in case we want to render links on items to allow to go to their definition.
2223
crate struct ContextInfo<'a, 'b, 'c> {
2324
crate context: &'a Context<'b>,
24-
/// This represents the "lo" bytes of the current file we're rendering. To get a [`Span`] from
25-
/// it, you just need to add add your current byte position in the string and its length (to get
26-
/// the "hi" part).
27-
///
28-
/// This is used to create a [`LightSpan`] which is then used as an index in the `span_map` in
29-
/// order to retrieve the definition's [`Span`] (which is used to generate the URL).
30-
crate file_span_lo: u32,
25+
/// This span contains the current file we're going through.
26+
crate file_span: Span,
3127
/// This field is used to know "how far" from the top of the directory we are to link to either
3228
/// documentation pages or other source pages.
3329
crate root_path: &'c str,
@@ -86,7 +82,6 @@ fn write_header(out: &mut Buffer, class: Option<&str>, extra_content: Option<Buf
8682
/// item definition.
8783
///
8884
/// More explanations about spans and how we use them here are provided in the
89-
/// [`LightSpan::new_in_file`] function documentation about how it works.
9085
fn write_code(
9186
out: &mut Buffer,
9287
src: &str,
@@ -95,7 +90,7 @@ fn write_code(
9590
) {
9691
// This replace allows to fix how the code source with DOS backline characters is displayed.
9792
let src = src.replace("\r\n", "\n");
98-
Classifier::new(&src, edition, context_info.as_ref().map(|c| c.file_span_lo).unwrap_or(0))
93+
Classifier::new(&src, edition, context_info.as_ref().map(|c| c.file_span).unwrap_or(DUMMY_SP))
9994
.highlight(&mut |highlight| {
10095
match highlight {
10196
Highlight::Token { text, class } => string(out, Escape(text), class, &context_info),
@@ -118,14 +113,14 @@ enum Class {
118113
KeyWord,
119114
// Keywords that do pointer/reference stuff.
120115
RefKeyWord,
121-
Self_(LightSpan),
116+
Self_(Span),
122117
Op,
123118
Macro,
124119
MacroNonTerminal,
125120
String,
126121
Number,
127122
Bool,
128-
Ident(LightSpan),
123+
Ident(Span),
129124
Lifetime,
130125
PreludeTy,
131126
PreludeVal,
@@ -158,7 +153,7 @@ impl Class {
158153

159154
/// In case this is an item which can be converted into a link to a definition, it'll contain
160155
/// a "span" (a tuple representing `(lo, hi)` equivalent of `Span`).
161-
fn get_span(self) -> Option<LightSpan> {
156+
fn get_span(self) -> Option<Span> {
162157
match self {
163158
Self::Ident(sp) | Self::Self_(sp) => Some(sp),
164159
_ => None,
@@ -213,15 +208,14 @@ struct Classifier<'a> {
213208
in_macro_nonterminal: bool,
214209
edition: Edition,
215210
byte_pos: u32,
216-
file_span_lo: u32,
211+
file_span: Span,
217212
src: &'a str,
218213
}
219214

220215
impl<'a> Classifier<'a> {
221216
/// Takes as argument the source code to HTML-ify, the rust edition to use and the source code
222-
/// file "lo" byte which we be used later on by the `span_correspondance_map`. More explanations
223-
/// are provided in the [`LightSpan::new_in_file`] function documentation about how it works.
224-
fn new(src: &str, edition: Edition, file_span_lo: u32) -> Classifier<'_> {
217+
/// file span which will be used later on by the `span_correspondance_map`.
218+
fn new(src: &str, edition: Edition, file_span: Span) -> Classifier<'_> {
225219
let tokens = TokenIter { src }.peekable();
226220
Classifier {
227221
tokens,
@@ -230,15 +224,16 @@ impl<'a> Classifier<'a> {
230224
in_macro_nonterminal: false,
231225
edition,
232226
byte_pos: 0,
233-
file_span_lo,
227+
file_span,
234228
src,
235229
}
236230
}
237231

238-
/// Convenient wrapper around [`LightSpan::new_in_file`] to prevent passing the `file_span_lo`
239-
/// argument every time.
240-
fn new_light_span(&self, lo: u32, hi: u32) -> LightSpan {
241-
LightSpan::new_in_file(self.file_span_lo, lo, hi)
232+
/// Convenient wrapper to create a [`Span`] from a position in the file.
233+
fn new_span(&self, lo: u32, text: &str) -> Span {
234+
let hi = lo + text.len() as u32;
235+
let file_lo = self.file_span.lo();
236+
self.file_span.with_lo(file_lo + BytePos(lo)).with_hi(file_lo + BytePos(hi))
242237
}
243238

244239
/// Concatenate colons and idents as one when possible.
@@ -487,15 +482,13 @@ impl<'a> Classifier<'a> {
487482
self.in_macro_nonterminal = false;
488483
Class::MacroNonTerminal
489484
}
490-
"self" | "Self" => {
491-
Class::Self_(self.new_light_span(before, before + text.len() as u32))
492-
}
493-
_ => Class::Ident(self.new_light_span(before, before + text.len() as u32)),
485+
"self" | "Self" => Class::Self_(self.new_span(before, text)),
486+
_ => Class::Ident(self.new_span(before, text)),
494487
},
495488
Some(c) => c,
496489
},
497490
TokenKind::RawIdent | TokenKind::UnknownPrefix => {
498-
Class::Ident(self.new_light_span(before, before + text.len() as u32))
491+
Class::Ident(self.new_span(before, text))
499492
}
500493
TokenKind::Lifetime { .. } => Class::Lifetime,
501494
};
@@ -560,7 +553,7 @@ fn string<T: Display>(
560553
"self" | "Self" => write!(
561554
&mut path,
562555
"<span class=\"{}\">{}</span>",
563-
Class::Self_(LightSpan::dummy()).as_html(),
556+
Class::Self_(DUMMY_SP).as_html(),
564557
t
565558
),
566559
"crate" | "super" => {

src/librustdoc/html/render/context.rs

+3-3
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, LightSpan, LinkFromSrc, NameDoc,
22-
StylePath, BASIC_KEYWORDS,
21+
collect_spans_and_sources, print_sidebar, settings, AllTypes, LinkFromSrc, NameDoc, StylePath,
22+
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<LightSpan, LinkFromSrc>,
134+
crate span_correspondance_map: FxHashMap<rustc_span::Span, LinkFromSrc>,
135135
}
136136

137137
impl SharedContext<'_> {

src/librustdoc/html/render/mod.rs

+1-1
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, LightSpan, LinkFromSrc};
37+
crate use span_map::{collect_spans_and_sources, LinkFromSrc};
3838

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

src/librustdoc/html/render/span_map.rs

+8-53
Original file line numberDiff line numberDiff line change
@@ -24,43 +24,6 @@ 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 dummy() -> 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-
6427
/// This function will do at most two things:
6528
///
6629
/// 1. Generate a `span` correspondance map which links an item `span` to its definition `span`.
@@ -77,7 +40,7 @@ crate fn collect_spans_and_sources(
7740
src_root: &Path,
7841
include_sources: bool,
7942
generate_link_to_definition: bool,
80-
) -> (clean::Crate, FxHashMap<PathBuf, String>, FxHashMap<LightSpan, LinkFromSrc>) {
43+
) -> (clean::Crate, FxHashMap<PathBuf, String>, FxHashMap<Span, LinkFromSrc>) {
8144
let mut visitor = SpanMapVisitor { tcx, matches: FxHashMap::default() };
8245

8346
if include_sources {
@@ -93,7 +56,7 @@ crate fn collect_spans_and_sources(
9356

9457
struct SpanMapVisitor<'tcx> {
9558
crate tcx: TyCtxt<'tcx>,
96-
crate matches: FxHashMap<LightSpan, LinkFromSrc>,
59+
crate matches: FxHashMap<Span, LinkFromSrc>,
9760
}
9861

9962
impl<'tcx> SpanMapVisitor<'tcx> {
@@ -115,18 +78,12 @@ impl<'tcx> SpanMapVisitor<'tcx> {
11578
};
11679
if let Some(span) = self.tcx.hir().res_span(path.res) {
11780
self.matches.insert(
118-
path_span
119-
.map(LightSpan::new_from_span)
120-
.unwrap_or_else(|| LightSpan::new_from_span(path.span)),
81+
path_span.unwrap_or_else(|| path.span),
12182
LinkFromSrc::Local(clean::Span::new(span)),
12283
);
12384
} else if let Some(def_id) = info {
124-
self.matches.insert(
125-
path_span
126-
.map(LightSpan::new_from_span)
127-
.unwrap_or_else(|| LightSpan::new_from_span(path.span)),
128-
LinkFromSrc::External(def_id),
129-
);
85+
self.matches
86+
.insert(path_span.unwrap_or_else(|| path.span), LinkFromSrc::External(def_id));
13087
}
13188
}
13289
}
@@ -163,10 +120,8 @@ impl Visitor<'tcx> for SpanMapVisitor<'tcx> {
163120
if let Some(node) = self.tcx.hir().find(id) {
164121
match node {
165122
Node::Item(item) => {
166-
self.matches.insert(
167-
LightSpan::new_from_span(item.ident.span),
168-
LinkFromSrc::Local(clean::Span::new(m.inner)),
169-
);
123+
self.matches
124+
.insert(item.ident.span, LinkFromSrc::Local(clean::Span::new(m.inner)));
170125
}
171126
_ => {}
172127
}
@@ -188,7 +143,7 @@ impl Visitor<'tcx> for SpanMapVisitor<'tcx> {
188143
});
189144
if let Some(def_id) = typeck_results.type_dependent_def_id(expr.hir_id) {
190145
self.matches.insert(
191-
LightSpan::new_from_span(method_span),
146+
method_span,
192147
match hir.span_if_local(def_id) {
193148
Some(span) => LinkFromSrc::Local(clean::Span::new(span)),
194149
None => LinkFromSrc::External(def_id),

src/librustdoc/html/sources.rs

+11-13
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,14 @@ impl DocFolder for SourceCollector<'_, '_> {
111111
if self.cx.include_sources && is_real_and_local(span, sess) {
112112
let filename = span.filename(sess);
113113
let span = span.inner();
114-
let start_pos = sess.source_map().lookup_source_file(span.lo()).start_pos;
114+
let pos = sess.source_map().lookup_source_file(span.lo());
115+
let file_span = span.with_lo(pos.start_pos).with_hi(pos.end_pos);
115116
// If it turns out that we couldn't read this file, then we probably
116117
// can't read any of the files (generating html output from json or
117118
// something like that), so just don't include sources for the
118119
// entire crate. The other option is maintaining this mapping on a
119120
// per-file basis, but that's probably not worth it...
120-
self.cx.include_sources = match self.emit_source(&filename, start_pos.0) {
121+
self.cx.include_sources = match self.emit_source(&filename, file_span) {
121122
Ok(()) => true,
122123
Err(e) => {
123124
self.cx.shared.tcx.sess.span_err(
@@ -140,7 +141,11 @@ impl DocFolder for SourceCollector<'_, '_> {
140141

141142
impl SourceCollector<'_, 'tcx> {
142143
/// Renders the given filename into its corresponding HTML source file.
143-
fn emit_source(&mut self, filename: &FileName, file_span_lo: u32) -> Result<(), Error> {
144+
fn emit_source(
145+
&mut self,
146+
filename: &FileName,
147+
file_span: rustc_span::Span,
148+
) -> Result<(), Error> {
144149
let p = match *filename {
145150
FileName::Real(ref file) => {
146151
if let Some(local_path) = file.local_path() {
@@ -200,14 +205,7 @@ impl SourceCollector<'_, 'tcx> {
200205
&page,
201206
"",
202207
|buf: &mut _| {
203-
print_src(
204-
buf,
205-
contents,
206-
self.cx.shared.edition(),
207-
file_span_lo,
208-
&self.cx,
209-
&root_path,
210-
)
208+
print_src(buf, contents, self.cx.shared.edition(), file_span, &self.cx, &root_path)
211209
},
212210
&self.cx.shared.style_files,
213211
);
@@ -250,7 +248,7 @@ fn print_src(
250248
buf: &mut Buffer,
251249
s: &str,
252250
edition: Edition,
253-
file_span_lo: u32,
251+
file_span: rustc_span::Span,
254252
context: &Context<'_>,
255253
root_path: &str,
256254
) {
@@ -275,6 +273,6 @@ fn print_src(
275273
None,
276274
edition,
277275
Some(line_numbers),
278-
Some(highlight::ContextInfo { context, file_span_lo, root_path }),
276+
Some(highlight::ContextInfo { context, file_span, root_path }),
279277
);
280278
}

0 commit comments

Comments
 (0)