diff options
| author | Simonas Kazlauskas <git@kazlauskas.me> | 2015-06-16 21:47:09 +0300 |
|---|---|---|
| committer | Simonas Kazlauskas <git@kazlauskas.me> | 2015-06-16 21:47:09 +0300 |
| commit | 7ff55eaf258a708217fd9e4b998ee050375c385d (patch) | |
| tree | 75dd220739b075e2c796257fe50ea42dd9808dce /src/libsyntax/codemap.rs | |
| parent | 73fb19c04ac227fe2aad2c618f76b6eb05dd7ec9 (diff) | |
| download | rust-7ff55eaf258a708217fd9e4b998ee050375c385d.tar.gz rust-7ff55eaf258a708217fd9e4b998ee050375c385d.zip | |
Fix file!(), line!() and column!() macros
These used to return wrong results in case they were expanded inside compiler’s iternal syntax sugar (closures, if-let) expansions Fixes #26322
Diffstat (limited to 'src/libsyntax/codemap.rs')
| -rw-r--r-- | src/libsyntax/codemap.rs | 97 |
1 files changed, 44 insertions, 53 deletions
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 98225d10400..ea27ed6b360 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -17,7 +17,7 @@ //! within the CodeMap, which upon request can be converted to line and column //! information, source code snippets, etc. -pub use self::MacroFormat::*; +pub use self::ExpnFormat::*; use std::cell::RefCell; use std::ops::{Add, Sub}; @@ -228,17 +228,17 @@ pub struct FileMapAndBytePos { pub fm: Rc<FileMap>, pub pos: BytePos } // _____________________________________________________________________________ -// MacroFormat, NameAndSpan, ExpnInfo, ExpnId +// ExpnFormat, NameAndSpan, ExpnInfo, ExpnId // -/// The syntax with which a macro was invoked. -#[derive(Clone, Copy, Hash, Debug)] -pub enum MacroFormat { +/// The source of expansion. +#[derive(Clone, Copy, Hash, Debug, PartialEq, Eq)] +pub enum ExpnFormat { /// e.g. #[derive(...)] <item> MacroAttribute, /// e.g. `format!()` MacroBang, - /// Expansion performed by the compiler (libsyntax::expand). + /// Syntax sugar expansion performed by the compiler (libsyntax::expand). CompilerExpansion, } @@ -248,7 +248,7 @@ pub struct NameAndSpan { /// with this Span. pub name: String, /// The format with which the macro was invoked. - pub format: MacroFormat, + pub format: ExpnFormat, /// Whether the macro is allowed to use #[unstable]/feature-gated /// features internally without forcing the whole crate to opt-in /// to them. @@ -259,11 +259,11 @@ pub struct NameAndSpan { pub span: Option<Span> } -/// Extra information for tracking macro expansion of spans +/// Extra information for tracking spans of macro and syntax sugar expansion #[derive(Hash, Debug)] pub struct ExpnInfo { - /// The location of the actual macro invocation, e.g. `let x = - /// foo!();` + /// The location of the actual macro invocation or syntax sugar , e.g. + /// `let x = foo!();` or `if let Some(y) = x {}` /// /// This may recursively refer to other macro invocations, e.g. if /// `foo!()` invoked `bar!()` internally, and there was an @@ -272,12 +272,7 @@ pub struct ExpnInfo { /// call_site span would have its own ExpnInfo, with the call_site /// pointing to the `foo!` invocation. pub call_site: Span, - /// Information about the macro and its definition. - /// - /// The `callee` of the inner expression in the `call_site` - /// example would point to the `macro_rules! bar { ... }` and that - /// of the `bar!()` invocation would point to the `macro_rules! - /// foo { ... }`. + /// Information about the expansion. pub callee: NameAndSpan } @@ -677,7 +672,39 @@ impl CodeMap { /// Lookup source information about a BytePos pub fn lookup_char_pos(&self, pos: BytePos) -> Loc { - self.lookup_pos(pos) + let FileMapAndLine {fm: f, line: a} = self.lookup_line(pos); + let line = a + 1; // Line numbers start at 1 + let chpos = self.bytepos_to_file_charpos(pos); + let linebpos = (*f.lines.borrow())[a]; + let linechpos = self.bytepos_to_file_charpos(linebpos); + debug!("byte pos {:?} is on the line at byte pos {:?}", + pos, linebpos); + debug!("char pos {:?} is on the line at char pos {:?}", + chpos, linechpos); + debug!("byte is on line: {}", line); + assert!(chpos >= linechpos); + Loc { + file: f, + line: line, + col: chpos - linechpos + } + } + + fn lookup_line(&self, pos: BytePos) -> FileMapAndLine { + let idx = self.lookup_filemap_idx(pos); + + let files = self.files.borrow(); + let f = (*files)[idx].clone(); + let mut a = 0; + { + let lines = f.lines.borrow(); + let mut b = lines.len(); + while b - a > 1 { + let m = (a + b) / 2; + if (*lines)[m] > pos { b = m; } else { a = m; } + } + } + FileMapAndLine {fm: f, line: a} } pub fn lookup_char_pos_adj(&self, pos: BytePos) -> LocWithOpt { @@ -877,42 +904,6 @@ impl CodeMap { return a; } - fn lookup_line(&self, pos: BytePos) -> FileMapAndLine { - let idx = self.lookup_filemap_idx(pos); - - let files = self.files.borrow(); - let f = (*files)[idx].clone(); - let mut a = 0; - { - let lines = f.lines.borrow(); - let mut b = lines.len(); - while b - a > 1 { - let m = (a + b) / 2; - if (*lines)[m] > pos { b = m; } else { a = m; } - } - } - FileMapAndLine {fm: f, line: a} - } - - fn lookup_pos(&self, pos: BytePos) -> Loc { - let FileMapAndLine {fm: f, line: a} = self.lookup_line(pos); - let line = a + 1; // Line numbers start at 1 - let chpos = self.bytepos_to_file_charpos(pos); - let linebpos = (*f.lines.borrow())[a]; - let linechpos = self.bytepos_to_file_charpos(linebpos); - debug!("byte pos {:?} is on the line at byte pos {:?}", - pos, linebpos); - debug!("char pos {:?} is on the line at char pos {:?}", - chpos, linechpos); - debug!("byte is on line: {}", line); - assert!(chpos >= linechpos); - Loc { - file: f, - line: line, - col: chpos - linechpos - } - } - pub fn record_expansion(&self, expn_info: ExpnInfo) -> ExpnId { let mut expansions = self.expansions.borrow_mut(); expansions.push(expn_info); |
