// option. This file may not be copied, modified, or distributed
// except according to those terms.
-//! The source positions and related helper functions
+//! The source positions and related helper functions.
//!
-//! # Note
+//! ## Note
//!
//! This API is completely unstable and subject to change.
#![feature(specialization)]
#![cfg_attr(not(stage0), feature(stdsimd))]
-use std::borrow::Cow;
-use std::cell::Cell;
-use std::cmp::{self, Ordering};
-use std::fmt;
-use std::hash::{Hasher, Hash};
-use std::ops::{Add, Sub};
-use std::path::PathBuf;
-
-use rustc_data_structures::stable_hasher::StableHasher;
-use rustc_data_structures::sync::{Lrc, Lock};
-
extern crate arena;
extern crate rustc_data_structures;
mod analyze_source_file;
+use rustc_data_structures::stable_hasher::StableHasher;
+use rustc_data_structures::sync::{Lrc, Lock};
+
+use std::borrow::Cow;
+use std::cell::Cell;
+use std::cmp::{self, Ordering};
+use std::fmt;
+use std::hash::{Hasher, Hash};
+use std::ops::{Add, Sub};
+use std::path::PathBuf;
+
pub struct Globals {
symbol_interner: Lock<symbol::Interner>,
span_interner: Lock<span_encoding::SpanInterner>,
scoped_thread_local!(pub static GLOBALS: Globals);
-/// Differentiates between real files and common virtual files
+/// Differentiates between real files and common virtual files.
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash, RustcDecodable, RustcEncodable)]
pub enum FileName {
Real(PathBuf),
/// A macro. This includes the full name of the macro, so that there are no clashes.
Macros(String),
- /// call to `quote!`
+ /// Call to `quote!`.
QuoteExpansion(u64),
- /// Command line
+ /// Command line.
Anon(u64),
- /// Hack in src/libsyntax/parse.rs
- /// FIXME(jseyfried)
+ /// Hack in `src/libsyntax/parse.rs`.
+ // FIXME(jseyfried)
MacroExpansion(u64),
ProcMacroSourceCode(u64),
- /// Strings provided as --cfg [cfgspec] stored in a crate_cfg
+ /// Strings provided as `--cfg [cfgspec]` stored in a `crate_cfg`.
CfgSpec(u64),
- /// Strings provided as crate attributes in the CLI
+ /// Strings provided as crate attributes in the CLI.
CliCrateAttr(u64),
- /// Custom sources for explicit parser calls from plugins and drivers
+ /// Custom sources for explicit parser calls from plugins and drivers.
Custom(String),
DocTest(PathBuf, isize),
}
/// Spans represent a region of code, used for error reporting. Positions in spans
/// are *absolute* positions from the beginning of the source_map, not positions
-/// relative to SourceFiles. Methods on the SourceMap can be used to relate spans back
+/// relative to `SourceFile`s. Methods on the `SourceMap` can be used to relate spans back
/// to the original source.
/// You must be careful if the span crosses more than one file - you will not be
/// able to use many of the functions on spans in source_map and you cannot assume
-/// that the length of the span = hi - lo; there may be space in the BytePos
+/// that the length of the `span = hi - lo`; there may be space in the `BytePos`
/// range between files.
///
/// `SpanData` is public because `Span` uses a thread-local interner and can't be
}
// The interner is pointed to by a thread local value which is only set on the main thread
-// with parallelization is disabled. So we don't allow Span to transfer between threads
+// with parallelization is disabled. So we don't allow `Span` to transfer between threads
// to avoid panics and other errors, even though it would be memory safe to do so.
#[cfg(not(parallel_queries))]
impl !Send for Span {}
/// A collection of spans. Spans have two orthogonal attributes:
///
-/// - they can be *primary spans*. In this case they are the locus of
+/// - They can be *primary spans*. In this case they are the locus of
/// the error, and would be rendered with `^^^`.
-/// - they can have a *label*. In this case, the label is written next
+/// - They can have a *label*. In this case, the label is written next
/// to the mark in the snippet when we render.
#[derive(Clone, Debug, Hash, PartialEq, Eq, RustcEncodable, RustcDecodable)]
pub struct MultiSpan {
let span = self.data();
span.with_hi(span.lo)
}
- /// Returns a new span representing an empty span at the end of this span
+ /// Returns a new span representing an empty span at the end of this span.
#[inline]
pub fn shrink_to_hi(self) -> Span {
let span = self.data();
if self.is_dummy() { other } else { self }
}
- /// Return true if `self` fully encloses `other`.
+ /// Return `true` if `self` fully encloses `other`.
pub fn contains(self, other: Span) -> bool {
let span = self.data();
let other = other.data();
span.lo == other.lo && span.hi == other.hi
}
- /// Returns `Some(span)`, where the start is trimmed by the end of `other`
+ /// Returns `Some(span)`, where the start is trimmed by the end of `other`.
pub fn trim_start(self, other: Span) -> Option<Span> {
let span = self.data();
let other = other.data();
}
}
- /// Return the source span - this is either the supplied span, or the span for
+ /// Return the source span -- this is either the supplied span, or the span for
/// the macro callsite that expanded to it.
pub fn source_callsite(self) -> Span {
self.ctxt().outer().expn_info().map(|info| info.call_site.source_callsite()).unwrap_or(self)
}
/// The `Span` for the tokens in the previous macro expansion from which `self` was generated,
- /// if any
+ /// if any.
pub fn parent(self) -> Option<Span> {
self.ctxt().outer().expn_info().map(|i| i.call_site)
}
self.ctxt().outer().expn_info().map(source_callee)
}
- /// Check if a span is "internal" to a macro in which #[unstable]
+ /// Check if a span is "internal" to a macro in which `#[unstable]`
/// items can be used (that is, a macro marked with
/// `#[allow_internal_unstable]`).
pub fn allows_unstable(&self) -> bool {
}
}
- /// Return the compiler desugaring that created this span, or None
+ /// Return the compiler desugaring that created this span, or `None`
/// if this span is not from a desugaring.
pub fn compiler_desugaring_kind(&self) -> Option<CompilerDesugaringKind> {
match self.ctxt().outer().expn_info() {
let mut prev_span = DUMMY_SP;
let mut result = vec![];
while let Some(info) = self.ctxt().outer().expn_info() {
- // Don't print recursive invocations
+ // Don't print recursive invocations.
if !info.call_site.source_equal(&prev_span) {
let (pre, post) = match info.format {
ExpnFormat::MacroAttribute(..) => ("#[", "]"),
pub fn to(self, end: Span) -> Span {
let span_data = self.data();
let end_data = end.data();
- // FIXME(jseyfried): self.ctxt should always equal end.ctxt here (c.f. issue #23480)
+ // FIXME(jseyfried): `self.ctxt` should always equal `end.ctxt` here (cf. issue #23480).
// Return the macro span on its own to avoid weird diagnostic output. It is preferable to
// have an incomplete span than a completely nonsensical one.
if span_data.ctxt != end_data.ctxt {
} else if end_data.ctxt == SyntaxContext::empty() {
return self;
}
- // both span fall within a macro
- // FIXME(estebank) check if it is the *same* macro
+ // Both spans fall within a macro.
+ // FIXME(estebank): check if it is the *same* macro.
}
Span::new(
cmp::min(span_data.lo, end_data.lo),
}
}
-fn default_span_debug(span: Span, f: &mut fmt::Formatter) -> fmt::Result {
+pub fn default_span_debug(span: Span, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Span")
.field("lo", &span.lo())
.field("hi", &span.hi())
self.span_labels.push((span, label));
}
- /// Selects the first primary span (if any)
+ /// Selects the first primary span (if any).
pub fn primary_span(&self) -> Option<Span> {
self.primary_spans.first().cloned()
}
is_dummy
}
- /// Replaces all occurrences of one Span with another. Used to move Spans in areas that don't
+ /// Replaces all occurrences of one Span with another. Used to move `Span`s in areas that don't
/// display well (like std macros). Returns true if replacements occurred.
pub fn replace(&mut self, before: Span, after: Span) -> bool {
let mut replacements_occurred = false;
/// Returns the strings to highlight. We always ensure that there
/// is an entry for each of the primary spans -- for each primary
- /// span P, if there is at least one label with span P, we return
+ /// span `P`, if there is at least one label with span `P`, we return
/// those labels (marked as primary). But otherwise we return
/// `SpanLabel` instances with empty labels.
pub fn span_labels(&self) -> Vec<SpanLabel> {
pub const NO_EXPANSION: SyntaxContext = SyntaxContext::empty();
-/// Identifies an offset of a multi-byte character in a SourceFile
+/// Identifies an offset of a multi-byte character in a `SourceFile`.
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Eq, PartialEq, Debug)]
pub struct MultiByteChar {
- /// The absolute offset of the character in the SourceMap
+ /// The absolute offset of the character in the `SourceMap`.
pub pos: BytePos,
- /// The number of bytes, >=2
+ /// The number of bytes, `>= 2`.
pub bytes: u8,
}
-/// Identifies an offset of a non-narrow character in a SourceFile
+/// Identifies an offset of a non-narrow character in a `SourceFile`.
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Eq, PartialEq, Debug)]
pub enum NonNarrowChar {
- /// Represents a zero-width character
+ /// Represents a zero-width character.
ZeroWidth(BytePos),
- /// Represents a wide (fullwidth) character
+ /// Represents a wide (full-width) character.
Wide(BytePos),
- /// Represents a tab character, represented visually with a width of 4 characters
+ /// Represents a tab character, represented visually with a width of 4 characters.
Tab(BytePos),
}
}
}
- /// Returns the absolute offset of the character in the SourceMap
+ /// Returns the absolute offset of the character in the `SourceMap`.
pub fn pos(&self) -> BytePos {
match *self {
NonNarrowChar::ZeroWidth(p) |
}
}
- /// Returns the width of the character, 0 (zero-width) or 2 (wide)
+ /// Returns the width of the character, 0 (zero-width) or 2 (wide).
pub fn width(&self) -> usize {
match *self {
NonNarrowChar::ZeroWidth(_) => 0,
}
}
-/// The state of the lazy external source loading mechanism of a SourceFile.
+/// The state of the lazy external source loading mechanism of a `SourceFile`.
#[derive(PartialEq, Eq, Clone)]
pub enum ExternalSource {
/// The external source has been loaded already.
AbsentOk,
/// A failed attempt has been made to load the external source.
AbsentErr,
- /// No external source has to be loaded, since the SourceFile represents a local crate.
+ /// No external source has to be loaded, since the `SourceFile` represents a local crate.
Unneeded,
}
}
}
-/// A single source in the SourceMap.
+/// A single source in the `SourceMap`.
#[derive(Clone)]
pub struct SourceFile {
/// The name of the file that the source came from, source that doesn't
- /// originate from files has names between angle brackets by convention,
- /// e.g. `<anon>`
+ /// originate from files has names between angle brackets by convention
+ /// (e.g., `<anon>`).
pub name: FileName,
- /// True if the `name` field above has been modified by --remap-path-prefix
+ /// True if the `name` field above has been modified by `--remap-path-prefix`.
pub name_was_remapped: bool,
/// The unmapped path of the file that the source came from.
- /// Set to `None` if the SourceFile was imported from an external crate.
+ /// Set to `None` if the `SourceFile` was imported from an external crate.
pub unmapped_path: Option<FileName>,
- /// Indicates which crate this SourceFile was imported from.
+ /// Indicates which crate this `SourceFile` was imported from.
pub crate_of_origin: u32,
- /// The complete source code
+ /// The complete source code.
pub src: Option<Lrc<String>>,
- /// The source code's hash
+ /// The source code's hash.
pub src_hash: u128,
/// The external source code (used for external crates, which will have a `None`
/// value as `self.src`.
pub external_src: Lock<ExternalSource>,
- /// The start position of this source in the SourceMap
+ /// The start position of this source in the `SourceMap`.
pub start_pos: BytePos,
- /// The end position of this source in the SourceMap
+ /// The end position of this source in the `SourceMap`.
pub end_pos: BytePos,
- /// Locations of lines beginnings in the source code
+ /// Locations of lines beginnings in the source code.
pub lines: Vec<BytePos>,
- /// Locations of multi-byte characters in the source code
+ /// Locations of multi-byte characters in the source code.
pub multibyte_chars: Vec<MultiByteChar>,
- /// Width of characters that are not narrow in the source code
+ /// Width of characters that are not narrow in the source code.
pub non_narrow_chars: Vec<NonNarrowChar>,
- /// A hash of the filename, used for speeding up the incr. comp. hashing.
+ /// A hash of the filename, used for speeding up hashing in incremental compilation.
pub name_hash: u128,
}
s.emit_struct_field("end_pos", 5, |s| self.end_pos.encode(s))?;
s.emit_struct_field("lines", 6, |s| {
let lines = &self.lines[..];
- // store the length
+ // Store the length.
s.emit_u32(lines.len() as u32)?;
if !lines.is_empty() {
}
}
- /// Return the BytePos of the beginning of the current line.
+ /// Return the `BytePos` of the beginning of the current line.
pub fn line_begin_pos(&self, pos: BytePos) -> BytePos {
let line_index = self.lookup_line(pos).unwrap();
self.lines[line_index]
}
/// Find the line containing the given position. The return value is the
- /// index into the `lines` array of this SourceFile, not the 1-based line
+ /// index into the `lines` array of this `SourceFile`, not the 1-based line
/// number. If the source_file is empty or the position is located before the
- /// first line, None is returned.
+ /// first line, `None` is returned.
pub fn lookup_line(&self, pos: BytePos) -> Option<usize> {
if self.lines.len() == 0 {
return None;
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub struct BytePos(pub u32);
-/// A character offset. Because of multibyte utf8 characters, a byte offset
-/// is not equivalent to a character offset. The SourceMap will convert BytePos
-/// values to CharPos values as necessary.
+/// A character offset. Because of multibyte UTF-8 characters, a byte offset
+/// is not equivalent to a character offset. The `SourceMap` will convert `BytePos`
+/// values to `CharPos` values as necessary.
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub struct CharPos(pub usize);
-// FIXME: Lots of boilerplate in these impls, but so far my attempts to fix
-// have been unsuccessful
+// FIXME: lots of boilerplate in these impls, but so far my attempts to fix
+// have been unsuccessful.
impl Pos for BytePos {
#[inline(always)]
// Loc, LocWithOpt, SourceFileAndLine, SourceFileAndBytePos
//
-/// A source code location used for error reporting
+/// A source code location used for error reporting.
#[derive(Debug, Clone)]
pub struct Loc {
- /// Information about the original source
+ /// Information about the original source.
pub file: Lrc<SourceFile>,
- /// The (1-based) line number
+ /// The (1-based) line number.
pub line: usize,
- /// The (0-based) column offset
+ /// The (0-based) column offset.
pub col: CharPos,
- /// The (0-based) column offset when displayed
+ /// The (0-based) column offset when displayed.
pub col_display: usize,
}
-/// A source code location used as the result of lookup_char_pos_adj
+/// A source code location used as the result of `lookup_char_pos_adj`.
// Actually, *none* of the clients use the filename *or* file field;
// perhaps they should just be removed.
#[derive(Debug)]
pub file: Option<Lrc<SourceFile>>,
}
-// used to be structural records. Better names, anyone?
+// Used to be structural records.
#[derive(Debug)]
pub struct SourceFileAndLine { pub sf: Lrc<SourceFile>, pub line: usize }
#[derive(Debug)]