diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 4555d98d2bfcd..3cdb1352bef95 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -14,20 +14,16 @@ use std::iter::Peekable; use rustc_lexer::{LiteralKind, TokenKind}; use rustc_span::edition::Edition; use rustc_span::symbol::Symbol; +use rustc_span::{BytePos, Span, DUMMY_SP}; use super::format::{self, Buffer}; -use super::render::{LightSpan, LinkFromSrc}; +use super::render::LinkFromSrc; /// This type is needed in case we want to render links on items to allow to go to their definition. crate struct ContextInfo<'a, 'b, 'c> { crate context: &'a Context<'b>, - /// This represents the "lo" bytes of the current file we're rendering. To get a [`Span`] from - /// it, you just need to add add your current byte position in the string and its length (to get - /// the "hi" part). - /// - /// This is used to create a [`LightSpan`] which is then used as an index in the `span_map` in - /// order to retrieve the definition's [`Span`] (which is used to generate the URL). - crate file_span_lo: u32, + /// This span contains the current file we're going through. + crate file_span: Span, /// This field is used to know "how far" from the top of the directory we are to link to either /// documentation pages or other source pages. crate root_path: &'c str, @@ -86,7 +82,6 @@ fn write_header(out: &mut Buffer, class: Option<&str>, extra_content: Option string(out, Escape(text), class, &context_info), @@ -118,14 +113,14 @@ enum Class { KeyWord, // Keywords that do pointer/reference stuff. RefKeyWord, - Self_(LightSpan), + Self_(Span), Op, Macro, MacroNonTerminal, String, Number, Bool, - Ident(LightSpan), + Ident(Span), Lifetime, PreludeTy, PreludeVal, @@ -158,7 +153,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 { + fn get_span(self) -> Option { match self { Self::Ident(sp) | Self::Self_(sp) => Some(sp), _ => None, @@ -213,15 +208,14 @@ struct Classifier<'a> { in_macro_nonterminal: bool, edition: Edition, byte_pos: u32, - file_span_lo: u32, + file_span: Span, src: &'a str, } 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 [`LightSpan::new_in_file`] function documentation about how it works. - fn new(src: &str, edition: Edition, file_span_lo: u32) -> Classifier<'_> { + /// file span which will be used later on by the `span_correspondance_map`. + fn new(src: &str, edition: Edition, file_span: Span) -> Classifier<'_> { let tokens = TokenIter { src }.peekable(); Classifier { tokens, @@ -230,15 +224,16 @@ impl<'a> Classifier<'a> { in_macro_nonterminal: false, edition, byte_pos: 0, - file_span_lo, + file_span, src, } } - /// Convenient wrapper around [`LightSpan::new_in_file`] to prevent passing the `file_span_lo` - /// argument every time. - fn new_light_span(&self, lo: u32, hi: u32) -> LightSpan { - LightSpan::new_in_file(self.file_span_lo, lo, hi) + /// Convenient wrapper to create a [`Span`] from a position in the file. + fn new_span(&self, lo: u32, text: &str) -> Span { + let hi = lo + text.len() as u32; + let file_lo = self.file_span.lo(); + self.file_span.with_lo(file_lo + BytePos(lo)).with_hi(file_lo + BytePos(hi)) } /// Concatenate colons and idents as one when possible. @@ -487,15 +482,13 @@ impl<'a> Classifier<'a> { self.in_macro_nonterminal = false; Class::MacroNonTerminal } - "self" | "Self" => { - Class::Self_(self.new_light_span(before, before + text.len() as u32)) - } - _ => Class::Ident(self.new_light_span(before, before + text.len() as u32)), + "self" | "Self" => Class::Self_(self.new_span(before, text)), + _ => Class::Ident(self.new_span(before, text)), }, Some(c) => c, }, TokenKind::RawIdent | TokenKind::UnknownPrefix => { - Class::Ident(self.new_light_span(before, before + text.len() as u32)) + Class::Ident(self.new_span(before, text)) } TokenKind::Lifetime { .. } => Class::Lifetime, }; @@ -560,7 +553,7 @@ fn string( "self" | "Self" => write!( &mut path, "{}", - Class::Self_(LightSpan::dummy()).as_html(), + Class::Self_(DUMMY_SP).as_html(), t ), "crate" | "super" => { diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 36ec2cf3f7a25..6ce0828e15940 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, LightSpan, LinkFromSrc, NameDoc, - StylePath, BASIC_KEYWORDS, + collect_spans_and_sources, print_sidebar, settings, AllTypes, 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, + crate span_correspondance_map: FxHashMap, } impl SharedContext<'_> { diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 584afdeb280fc..fd2e18a8be77f 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, LightSpan, LinkFromSrc}; +crate use span_map::{collect_spans_and_sources, 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 429673c96e787..b35cd45dc9a88 100644 --- a/src/librustdoc/html/render/span_map.rs +++ b/src/librustdoc/html/render/span_map.rs @@ -24,43 +24,6 @@ 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 dummy() -> 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`. @@ -77,7 +40,7 @@ crate fn collect_spans_and_sources( src_root: &Path, include_sources: bool, generate_link_to_definition: bool, -) -> (clean::Crate, FxHashMap, FxHashMap) { +) -> (clean::Crate, FxHashMap, FxHashMap) { let mut visitor = SpanMapVisitor { tcx, matches: FxHashMap::default() }; if include_sources { @@ -93,7 +56,7 @@ crate fn collect_spans_and_sources( struct SpanMapVisitor<'tcx> { crate tcx: TyCtxt<'tcx>, - crate matches: FxHashMap, + crate matches: FxHashMap, } impl<'tcx> SpanMapVisitor<'tcx> { @@ -115,18 +78,12 @@ impl<'tcx> SpanMapVisitor<'tcx> { }; if let Some(span) = self.tcx.hir().res_span(path.res) { self.matches.insert( - path_span - .map(LightSpan::new_from_span) - .unwrap_or_else(|| LightSpan::new_from_span(path.span)), + path_span.unwrap_or_else(|| path.span), LinkFromSrc::Local(clean::Span::new(span)), ); } else if let Some(def_id) = info { - self.matches.insert( - path_span - .map(LightSpan::new_from_span) - .unwrap_or_else(|| LightSpan::new_from_span(path.span)), - LinkFromSrc::External(def_id), - ); + self.matches + .insert(path_span.unwrap_or_else(|| path.span), LinkFromSrc::External(def_id)); } } } @@ -163,10 +120,8 @@ impl Visitor<'tcx> for SpanMapVisitor<'tcx> { if let Some(node) = self.tcx.hir().find(id) { match node { Node::Item(item) => { - self.matches.insert( - LightSpan::new_from_span(item.ident.span), - LinkFromSrc::Local(clean::Span::new(m.inner)), - ); + self.matches + .insert(item.ident.span, LinkFromSrc::Local(clean::Span::new(m.inner))); } _ => {} } @@ -188,7 +143,7 @@ impl Visitor<'tcx> for SpanMapVisitor<'tcx> { }); if let Some(def_id) = typeck_results.type_dependent_def_id(expr.hir_id) { self.matches.insert( - LightSpan::new_from_span(method_span), + method_span, match hir.span_if_local(def_id) { Some(span) => LinkFromSrc::Local(clean::Span::new(span)), None => LinkFromSrc::External(def_id), diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index 9204c94bd7639..73916e204d942 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -111,13 +111,14 @@ impl DocFolder for SourceCollector<'_, '_> { if self.cx.include_sources && is_real_and_local(span, sess) { let filename = span.filename(sess); let span = span.inner(); - let start_pos = sess.source_map().lookup_source_file(span.lo()).start_pos; + let pos = sess.source_map().lookup_source_file(span.lo()); + let file_span = span.with_lo(pos.start_pos).with_hi(pos.end_pos); // If it turns out that we couldn't read this file, then we probably // can't read any of the files (generating html output from json or // something like that), so just don't include sources for the // entire crate. The other option is maintaining this mapping on a // per-file basis, but that's probably not worth it... - self.cx.include_sources = match self.emit_source(&filename, start_pos.0) { + self.cx.include_sources = match self.emit_source(&filename, file_span) { Ok(()) => true, Err(e) => { self.cx.shared.tcx.sess.span_err( @@ -140,7 +141,11 @@ impl DocFolder for SourceCollector<'_, '_> { impl SourceCollector<'_, 'tcx> { /// Renders the given filename into its corresponding HTML source file. - fn emit_source(&mut self, filename: &FileName, file_span_lo: u32) -> Result<(), Error> { + fn emit_source( + &mut self, + filename: &FileName, + file_span: rustc_span::Span, + ) -> Result<(), Error> { let p = match *filename { FileName::Real(ref file) => { if let Some(local_path) = file.local_path() { @@ -200,14 +205,7 @@ impl SourceCollector<'_, 'tcx> { &page, "", |buf: &mut _| { - print_src( - buf, - contents, - self.cx.shared.edition(), - file_span_lo, - &self.cx, - &root_path, - ) + print_src(buf, contents, self.cx.shared.edition(), file_span, &self.cx, &root_path) }, &self.cx.shared.style_files, ); @@ -250,7 +248,7 @@ fn print_src( buf: &mut Buffer, s: &str, edition: Edition, - file_span_lo: u32, + file_span: rustc_span::Span, context: &Context<'_>, root_path: &str, ) { @@ -275,6 +273,6 @@ fn print_src( None, edition, Some(line_numbers), - Some(highlight::ContextInfo { context, file_span_lo, root_path }), + Some(highlight::ContextInfo { context, file_span, root_path }), ); }