Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7b69a13

Browse files
Auto merge of #147189 - yotamofek:pr/rustdoc/highlight-optimizations-2, r=<try>
[PERF] Use small `Span`s in rustdoc's highlighter
2 parents a2db928 + a2250d0 commit 7b69a13

File tree

4 files changed

+59
-17
lines changed

4 files changed

+59
-17
lines changed

‎src/librustdoc/html/highlight.rs‎

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ use std::iter;
1212

1313
use rustc_data_structures::fx::FxIndexMap;
1414
use rustc_lexer::{Cursor, FrontmatterAllowed, LiteralKind, TokenKind};
15+
use rustc_span::BytePos;
1516
use rustc_span::edition::Edition;
1617
use rustc_span::symbol::Symbol;
17-
use rustc_span::{BytePos, DUMMY_SP, Span};
1818

1919
use super::format;
2020
use crate::clean::PrimitiveType;
@@ -23,6 +23,38 @@ use crate::html::escape::EscapeBodyText;
2323
use crate::html::macro_expansion::ExpandedCode;
2424
use crate::html::render::{Context, LinkFromSrc};
2525

26+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
27+
pub(crate) struct Span {
28+
lo: BytePos,
29+
hi: BytePos,
30+
}
31+
32+
impl From<rustc_span::Span> for Span {
33+
fn from(value: rustc_span::Span) -> Self {
34+
Self { lo: value.lo(), hi: value.hi() }
35+
}
36+
}
37+
38+
impl Span {
39+
fn lo(self) -> BytePos {
40+
self.lo
41+
}
42+
43+
fn hi(self) -> BytePos {
44+
self.hi
45+
}
46+
47+
fn with_lo(self, lo: BytePos) -> Self {
48+
Self { lo, hi: self.hi() }
49+
}
50+
51+
fn with_hi(self, hi: BytePos) -> Span {
52+
Self { lo: self.lo(), hi }
53+
}
54+
}
55+
56+
const DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0) };
57+
2658
/// This type is needed in case we want to render links on items to allow to go to their definition.
2759
pub(crate) struct HrefContext<'a, 'tcx> {
2860
pub(crate) context: &'a Context<'tcx>,

‎src/librustdoc/html/render/context.rs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use crate::formats::FormatRenderer;
2828
use crate::formats::cache::Cache;
2929
use crate::formats::item_type::ItemType;
3030
use crate::html::escape::Escape;
31+
use crate::html::highlight::Span;
3132
use crate::html::macro_expansion::ExpandedCode;
3233
use crate::html::markdown::{self, ErrorCodes, IdMap, plain_text_summary};
3334
use crate::html::render::write_shared::write_shared;
@@ -139,7 +140,7 @@ pub(crate) struct SharedContext<'tcx> {
139140

140141
/// Correspondence map used to link types used in the source code pages to allow to click on
141142
/// links to jump to the type's definition.
142-
pub(crate) span_correspondence_map: FxHashMap<rustc_span::Span, LinkFromSrc>,
143+
pub(crate) span_correspondence_map: FxHashMap<Span, LinkFromSrc>,
143144
pub(crate) expanded_codes: FxHashMap<BytePos, Vec<ExpandedCode>>,
144145
/// The [`Cache`] used during rendering.
145146
pub(crate) cache: Cache,

‎src/librustdoc/html/render/span_map.rs‎

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ use rustc_hir::{ExprKind, HirId, Item, ItemKind, Mod, Node, QPath};
88
use rustc_middle::hir::nested_filter;
99
use rustc_middle::ty::TyCtxt;
1010
use rustc_span::hygiene::MacroKind;
11-
use rustc_span::{BytePos, ExpnKind,Span};
11+
use rustc_span::{BytePos, ExpnKind};
1212

1313
use crate::clean::{self, PrimitiveType, rustc_span};
14+
use crate::html::highlight::Span;
1415
use crate::html::sources;
1516

1617
/// This enum allows us to store two different kinds of information:
@@ -96,7 +97,7 @@ impl SpanMapVisitor<'_> {
9697
})
9798
.unwrap_or(path.span)
9899
};
99-
self.matches.insert(span, link);
100+
self.matches.insert(span.into(), link);
100101
}
101102
Res::Local(_) if let Some(span) = self.tcx.hir_res_span(path.res) => {
102103
let path_span = if only_use_last_segment
@@ -106,11 +107,12 @@ impl SpanMapVisitor<'_> {
106107
} else {
107108
path.span
108109
};
109-
self.matches.insert(path_span, LinkFromSrc::Local(clean::Span::new(span)));
110+
self.matches.insert(path_span.into(), LinkFromSrc::Local(clean::Span::new(span)));
110111
}
111112
Res::PrimTy(p) => {
112113
// FIXME: Doesn't handle "path-like" primitives like arrays or tuples.
113-
self.matches.insert(path.span, LinkFromSrc::Primitive(PrimitiveType::from(p)));
114+
self.matches
115+
.insert(path.span.into(), LinkFromSrc::Primitive(PrimitiveType::from(p)));
114116
}
115117
Res::Err => {}
116118
_ => {}
@@ -127,7 +129,7 @@ impl SpanMapVisitor<'_> {
127129
if cspan.inner().is_dummy() || cspan.cnum(self.tcx.sess) != LOCAL_CRATE {
128130
return;
129131
}
130-
self.matches.insert(span, LinkFromSrc::Doc(item.owner_id.to_def_id()));
132+
self.matches.insert(span.into(), LinkFromSrc::Doc(item.owner_id.to_def_id()));
131133
}
132134
}
133135

@@ -138,7 +140,7 @@ impl SpanMapVisitor<'_> {
138140
/// so, we loop until we find the macro definition by using `outer_expn_data` in a loop.
139141
/// Finally, we get the information about the macro itself (`span` if "local", `DefId`
140142
/// otherwise) and store it inside the span map.
141-
fn handle_macro(&mut self, span: Span) -> bool {
143+
fn handle_macro(&mut self, span: rustc_span::Span) -> bool {
142144
if !span.from_expansion() {
143145
return false;
144146
}
@@ -176,7 +178,7 @@ impl SpanMapVisitor<'_> {
176178
// The "call_site" includes the whole macro with its "arguments". We only want
177179
// the macro name.
178180
let new_span = new_span.with_hi(new_span.lo() + BytePos(macro_name.len() as u32));
179-
self.matches.insert(new_span, link_from_src);
181+
self.matches.insert(new_span.into(), link_from_src);
180182
true
181183
}
182184

@@ -233,7 +235,7 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
233235
intravisit::walk_path(self, path);
234236
}
235237

236-
fn visit_qpath(&mut self, qpath: &QPath<'tcx>, id: HirId, _span: Span) {
238+
fn visit_qpath(&mut self, qpath: &QPath<'tcx>, id: HirId, _span: rustc_span::Span) {
237239
match *qpath {
238240
QPath::TypeRelative(qself, path) => {
239241
if matches!(path.res, Res::Err) {
@@ -249,7 +251,7 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
249251
self.handle_path(&path, false);
250252
}
251253
} else {
252-
self.infer_id(path.hir_id, Some(id), path.ident.span);
254+
self.infer_id(path.hir_id, Some(id), path.ident.span.into());
253255
}
254256

255257
rustc_ast::visit::try_visit!(self.visit_ty_unambig(qself));
@@ -267,16 +269,18 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
267269
}
268270
}
269271

270-
fn visit_mod(&mut self, m: &'tcx Mod<'tcx>, span: Span, id: HirId) {
272+
fn visit_mod(&mut self, m: &'tcx Mod<'tcx>, span: rustc_span::Span, id: HirId) {
271273
// To make the difference between "mod foo {}" and "mod foo;". In case we "import" another
272274
// file, we want to link to it. Otherwise no need to create a link.
273275
if !span.overlaps(m.spans.inner_span) {
274276
// Now that we confirmed it's a file import, we want to get the span for the module
275277
// name only and not all the "mod foo;".
276278
if let Node::Item(item) = self.tcx.hir_node(id) {
277279
let (ident, _) = item.expect_mod();
278-
self.matches
279-
.insert(ident.span, LinkFromSrc::Local(clean::Span::new(m.spans.inner_span)));
280+
self.matches.insert(
281+
ident.span.into(),
282+
LinkFromSrc::Local(clean::Span::new(m.spans.inner_span)),
283+
);
280284
}
281285
} else {
282286
// If it's a "mod foo {}", we want to look to its documentation page.
@@ -288,9 +292,9 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
288292
fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'tcx>) {
289293
match expr.kind {
290294
ExprKind::MethodCall(segment, ..) => {
291-
self.infer_id(segment.hir_id, Some(expr.hir_id), segment.ident.span)
295+
self.infer_id(segment.hir_id, Some(expr.hir_id), segment.ident.span.into())
292296
}
293-
ExprKind::Call(call, ..) => self.infer_id(call.hir_id, None, call.span),
297+
ExprKind::Call(call, ..) => self.infer_id(call.hir_id, None, call.span.into()),
294298
_ => {
295299
if self.handle_macro(expr.span) {
296300
// We don't want to go deeper into the macro.

‎src/librustdoc/html/sources.rs‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,12 @@ pub(crate) fn print_src(
348348
highlight::write_code(
349349
fmt,
350350
s,
351-
Some(highlight::HrefContext { context, file_span, root_path, current_href }),
351+
Some(highlight::HrefContext {
352+
context,
353+
file_span: file_span.into(),
354+
root_path,
355+
current_href,
356+
}),
352357
Some(decoration_info),
353358
Some(line_info),
354359
);

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /