diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index 9d6720810b8..66355801b6c 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -24,7 +24,16 @@ use std::string; use std::iter; -use syntax_pos::Symbol; +use syntax_pos::{InnerSpan, Symbol}; + +#[derive(Copy, Clone)] +struct InnerOffset(usize); + +impl InnerOffset { + fn to(self, end: InnerOffset) -> InnerSpan { + InnerSpan::new(self.0, end.0) + } +} /// A piece is a portion of the format string which represents the next part /// to emit. These are emitted as a stream by the `Parser` class. @@ -136,9 +145,8 @@ pub struct ParseError { pub description: string::String, pub note: Option, pub label: string::String, - pub start: SpanIndex, - pub end: SpanIndex, - pub secondary_label: Option<(string::String, SpanIndex, SpanIndex)>, + pub span: InnerSpan, + pub secondary_label: Option<(string::String, InnerSpan)>, } /// The parser structure for interpreting the input format string. This is @@ -157,24 +165,15 @@ pub struct Parser<'a> { /// `Some(raw count)` when the string is "raw", used to position spans correctly style: Option, /// Start and end byte offset of every successfully parsed argument - pub arg_places: Vec<(SpanIndex, SpanIndex)>, + pub arg_places: Vec, /// Characters that need to be shifted skips: Vec, - /// Span offset of the last opening brace seen, used for error reporting - last_opening_brace_pos: Option, + /// Span of the last opening brace seen, used for error reporting + last_opening_brace: Option, /// Wether the source string is comes from `println!` as opposed to `format!` or `print!` append_newline: bool, } -#[derive(Clone, Copy, Debug)] -pub struct SpanIndex(pub usize); - -impl SpanIndex { - pub fn unwrap(self) -> usize { - self.0 - } -} - impl<'a> Iterator for Parser<'a> { type Item = Piece<'a>; @@ -182,19 +181,20 @@ fn next(&mut self) -> Option> { if let Some(&(pos, c)) = self.cur.peek() { match c { '{' => { - let curr_last_brace = self.last_opening_brace_pos; - self.last_opening_brace_pos = Some(self.to_span_index(pos)); + let curr_last_brace = self.last_opening_brace; + let byte_pos = self.to_span_index(pos); + self.last_opening_brace = Some(byte_pos.to(byte_pos)); self.cur.next(); if self.consume('{') { - self.last_opening_brace_pos = curr_last_brace; + self.last_opening_brace = curr_last_brace; Some(String(self.string(pos + 1))) } else { let arg = self.argument(); - if let Some(arg_pos) = self.must_consume('}').map(|end| { - (self.to_span_index(pos), self.to_span_index(end + 1)) - }) { - self.arg_places.push(arg_pos); + if let Some(end) = self.must_consume('}') { + let start = self.to_span_index(pos); + let end = self.to_span_index(end + 1); + self.arg_places.push(start.to(end)); } Some(NextArgument(arg)) } @@ -209,8 +209,7 @@ fn next(&mut self) -> Option> { "unmatched `}` found", "unmatched `}`", "if you intended to print `}`, you can escape it using `}}`", - err_pos, - err_pos, + err_pos.to(err_pos), ); None } @@ -242,7 +241,7 @@ pub fn new( style, arg_places: vec![], skips, - last_opening_brace_pos: None, + last_opening_brace: None, append_newline, } } @@ -254,15 +253,13 @@ fn err, S2: Into>( &mut self, description: S1, label: S2, - start: SpanIndex, - end: SpanIndex, + span: InnerSpan, ) { self.errors.push(ParseError { description: description.into(), note: None, label: label.into(), - start, - end, + span, secondary_label: None, }); } @@ -275,15 +272,13 @@ fn err_with_note, S2: Into, S3: Into bool { } } - fn to_span_index(&self, pos: usize) -> SpanIndex { + fn to_span_index(&self, pos: usize) -> InnerOffset { let mut pos = pos; let raw = self.style.map(|raw| raw + 1).unwrap_or(0); for skip in &self.skips { @@ -316,7 +311,7 @@ fn to_span_index(&self, pos: usize) -> SpanIndex { break; } } - SpanIndex(raw + pos + 1) + InnerOffset(raw + pos + 1) } /// Forces consumption of the specified character. If the character is not @@ -334,8 +329,8 @@ fn must_consume(&mut self, c: char) -> Option { let label = "expected `}`".to_owned(); let (note, secondary_label) = if c == '}' { (Some("if you intended to print `{`, you can escape it using `{{`".to_owned()), - self.last_opening_brace_pos.map(|pos| { - ("because of this opening brace".to_owned(), pos, pos) + self.last_opening_brace.map(|sp| { + ("because of this opening brace".to_owned(), sp) })) } else { (None, None) @@ -344,8 +339,7 @@ fn must_consume(&mut self, c: char) -> Option { description, note, label, - start: pos, - end: pos, + span: pos.to(pos), secondary_label, }); None @@ -359,8 +353,8 @@ fn must_consume(&mut self, c: char) -> Option { let label = format!("expected `{:?}`", c); let (note, secondary_label) = if c == '}' { (Some("if you intended to print `{`, you can escape it using `{{`".to_owned()), - self.last_opening_brace_pos.map(|pos| { - ("because of this opening brace".to_owned(), pos, pos) + self.last_opening_brace.map(|sp| { + ("because of this opening brace".to_owned(), sp) })) } else { (None, None) @@ -369,12 +363,11 @@ fn must_consume(&mut self, c: char) -> Option { description, note, label, - start: pos, - end: pos, + span: pos.to(pos), secondary_label, }); } else { - self.err(description, format!("expected `{:?}`", c), pos, pos); + self.err(description, format!("expected `{:?}`", c), pos.to(pos)); } None } @@ -446,8 +439,10 @@ fn position(&mut self) -> Option { self.err_with_note(format!("invalid argument name `{}`", invalid_name), "invalid argument name", "argument names cannot start with an underscore", - self.to_span_index(pos), - self.to_span_index(pos + invalid_name.len())); + self.to_span_index(pos).to( + self.to_span_index(pos + invalid_name.len()) + ), + ); Some(ArgumentNamed(Symbol::intern(invalid_name))) }, diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs index 694843ad7f7..6d51278b4e5 100644 --- a/src/librustdoc/passes/check_code_block_syntax.rs +++ b/src/librustdoc/passes/check_code_block_syntax.rs @@ -2,7 +2,7 @@ use syntax::parse::lexer::{StringReader as Lexer}; use syntax::parse::{ParseSess, token}; use syntax::source_map::FilePathMapping; -use syntax_pos::FileName; +use syntax_pos::{InnerSpan, FileName}; use crate::clean; use crate::core::DocContext; @@ -63,7 +63,7 @@ fn check_rust_syntax(&self, item: &clean::Item, dox: &str, code_block: RustCodeB } if code_block.syntax.is_none() && code_block.is_fenced { - let sp = sp.from_inner_byte_pos(0, 3); + let sp = sp.from_inner(InnerSpan::new(0, 3)); diag.span_suggestion( sp, "mark blocks that do not contain Rust code as text", diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 018ab5dea60..8fc6b9fdbe6 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -6,7 +6,7 @@ use rustc::middle::privacy::AccessLevels; use rustc::util::nodemap::DefIdSet; use std::mem; -use syntax_pos::{DUMMY_SP, Span}; +use syntax_pos::{DUMMY_SP, InnerSpan, Span}; use std::ops::Range; use crate::clean::{self, GetDefId, Item}; @@ -440,10 +440,10 @@ fn add_test(&mut self, _: String, _: LangString, _: usize) { } } - let sp = span_of_attrs(attrs).from_inner_byte_pos( + let sp = span_of_attrs(attrs).from_inner(InnerSpan::new( md_range.start + start_bytes, md_range.end + start_bytes + end_bytes, - ); + )); Some(sp) } diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 1fdc2e6274a..85b524786b2 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -900,15 +900,15 @@ fn find_skips(snippet: &str, is_raw: bool) -> Vec { if !parser.errors.is_empty() { let err = parser.errors.remove(0); - let sp = fmt.span.from_inner_byte_pos(err.start.unwrap(), err.end.unwrap()); + let sp = fmt.span.from_inner(err.span); let mut e = ecx.struct_span_err(sp, &format!("invalid format string: {}", err.description)); e.span_label(sp, err.label + " in format string"); if let Some(note) = err.note { e.note(¬e); } - if let Some((label, start, end)) = err.secondary_label { - let sp = fmt.span.from_inner_byte_pos(start.unwrap(), end.unwrap()); + if let Some((label, span)) = err.secondary_label { + let sp = fmt.span.from_inner(span); e.span_label(sp, label); } e.emit(); @@ -916,9 +916,7 @@ fn find_skips(snippet: &str, is_raw: bool) -> Vec { } let arg_spans = parser.arg_places.iter() - .map(|&(parse::SpanIndex(start), parse::SpanIndex(end))| { - fmt.span.from_inner_byte_pos(start, end) - }) + .map(|span| fmt.span.from_inner(*span)) .collect(); let mut cx = Context { @@ -1065,8 +1063,8 @@ macro_rules! check_foreign { show_doc_note = true; } - if let Some((start, end)) = pos { - let sp = fmt_sp.from_inner_byte_pos(start, end); + if let Some(inner_sp) = pos { + let sp = fmt_sp.from_inner(inner_sp); suggestions.push((sp, trn)); } else { diag.help(&format!("`{}` should be written as `{}`", sub, trn)); diff --git a/src/libsyntax_ext/format_foreign.rs b/src/libsyntax_ext/format_foreign.rs index b279dbced84..7ad5997bf2c 100644 --- a/src/libsyntax_ext/format_foreign.rs +++ b/src/libsyntax_ext/format_foreign.rs @@ -1,5 +1,6 @@ pub mod printf { use super::strcursor::StrCursor as Cur; + use syntax_pos::InnerSpan; /// Represents a single `printf`-style substitution. #[derive(Clone, PartialEq, Debug)] @@ -18,7 +19,7 @@ pub fn as_str(&self) -> &str { } } - pub fn position(&self) -> Option<(usize, usize)> { + pub fn position(&self) -> Option { match *self { Substitution::Format(ref fmt) => Some(fmt.position), _ => None, @@ -28,7 +29,7 @@ pub fn position(&self) -> Option<(usize, usize)> { pub fn set_position(&mut self, start: usize, end: usize) { match self { Substitution::Format(ref mut fmt) => { - fmt.position = (start, end); + fmt.position = InnerSpan::new(start, end); } _ => {} } @@ -65,7 +66,7 @@ pub struct Format<'a> { /// Type of parameter being converted. pub type_: &'a str, /// Byte offset for the start and end of this formatting directive. - pub position: (usize, usize), + pub position: InnerSpan, } impl Format<'_> { @@ -282,9 +283,9 @@ fn next(&mut self) -> Option { let (mut sub, tail) = parse_next_substitution(self.s)?; self.s = tail; match sub { - Substitution::Format(_) => if let Some((start, end)) = sub.position() { - sub.set_position(start + self.pos, end + self.pos); - self.pos += end; + Substitution::Format(_) => if let Some(inner_span) = sub.position() { + sub.set_position(inner_span.start + self.pos, inner_span.end + self.pos); + self.pos += inner_span.end; } Substitution::Escape => self.pos += 2, } @@ -373,7 +374,7 @@ macro_rules! move_to { precision: None, length: None, type_: at.slice_between(next).unwrap(), - position: (start.at, next.at), + position: InnerSpan::new(start.at, next.at), }), next.slice_after() )); @@ -560,7 +561,7 @@ macro_rules! move_to { drop(next); end = at; - let position = (start.at, end.at); + let position = InnerSpan::new(start.at, end.at); let f = Format { span: start.slice_between(end).unwrap(), @@ -650,7 +651,7 @@ macro_rules! assert_pns_eq_sub { precision: $prec, length: $len, type_: $type_, - position: $pos, + position: syntax_pos::InnerSpan::new($pos.0, $pos.1), }), "!" )) @@ -761,6 +762,7 @@ fn test_translation() { pub mod shell { use super::strcursor::StrCursor as Cur; + use syntax_pos::InnerSpan; #[derive(Clone, PartialEq, Debug)] pub enum Substitution<'a> { @@ -778,11 +780,11 @@ pub fn as_str(&self) -> String { } } - pub fn position(&self) -> Option<(usize, usize)> { + pub fn position(&self) -> Option { match self { Substitution::Ordinal(_, pos) | Substitution::Name(_, pos) | - Substitution::Escape(pos) => Some(*pos), + Substitution::Escape(pos) => Some(InnerSpan::new(pos.0, pos.1)), } } @@ -823,7 +825,7 @@ fn next(&mut self) -> Option { match parse_next_substitution(self.s) { Some((mut sub, tail)) => { self.s = tail; - if let Some((start, end)) = sub.position() { + if let Some(InnerSpan { start, end }) = sub.position() { sub.set_position(start + self.pos, end + self.pos); self.pos += end; } diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 8f5595968a7..bf0ab5fae4e 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -504,10 +504,10 @@ pub fn until(self, end: Span) -> Span { ) } - pub fn from_inner_byte_pos(self, start: usize, end: usize) -> Span { + pub fn from_inner(self, inner: InnerSpan) -> Span { let span = self.data(); - Span::new(span.lo + BytePos::from_usize(start), - span.lo + BytePos::from_usize(end), + Span::new(span.lo + BytePos::from_usize(inner.start), + span.lo + BytePos::from_usize(inner.end), span.ctxt) } @@ -1395,6 +1395,18 @@ pub struct MalformedSourceMapPositions { pub end_pos: BytePos } +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub struct InnerSpan { + pub start: usize, + pub end: usize, +} + +impl InnerSpan { + pub fn new(start: usize, end: usize) -> InnerSpan { + InnerSpan { start, end } + } +} + // Given a slice of line start positions and a position, returns the index of // the line the position is on. Returns -1 if the position is located before // the first line.