about summary refs log tree commit diff
path: root/src/librustc_builtin_macros/format.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustc_builtin_macros/format.rs')
-rw-r--r--src/librustc_builtin_macros/format.rs119
1 files changed, 11 insertions, 108 deletions
diff --git a/src/librustc_builtin_macros/format.rs b/src/librustc_builtin_macros/format.rs
index efce6288198..eed01b262bf 100644
--- a/src/librustc_builtin_macros/format.rs
+++ b/src/librustc_builtin_macros/format.rs
@@ -108,8 +108,6 @@ struct Context<'a, 'b> {
     arg_spans: Vec<Span>,
     /// All the formatting arguments that have formatting flags set, in order for diagnostics.
     arg_with_formatting: Vec<parse::FormatSpec<'a>>,
-    /// Whether this formatting string is a literal or it comes from a macro.
-    is_literal: bool,
 }
 
 /// Parses the arguments from the given list of tokens, returning the diagnostic
@@ -324,7 +322,7 @@ impl<'a, 'b> Context<'a, 'b> {
     /// format string.
     fn report_invalid_references(&self, numbered_position_args: bool) {
         let mut e;
-        let sp = if self.is_literal {
+        let sp = if !self.arg_spans.is_empty() {
             // Point at the formatting arguments.
             MultiSpan::from_spans(self.arg_spans.clone())
         } else {
@@ -372,7 +370,7 @@ impl<'a, 'b> Context<'a, 'b> {
                 let reg = refs.pop().unwrap();
                 (format!("arguments {head} and {tail}", head = refs.join(", "), tail = reg,), pos)
             };
-            if !self.is_literal {
+            if self.arg_spans.is_empty() {
                 sp = MultiSpan::from_span(self.fmtsp);
             }
 
@@ -502,11 +500,7 @@ impl<'a, 'b> Context<'a, 'b> {
                     }
                     None => {
                         let msg = format!("there is no argument named `{}`", name);
-                        let sp = if self.is_literal {
-                            *self.arg_spans.get(self.curpiece).unwrap_or(&self.fmtsp)
-                        } else {
-                            self.fmtsp
-                        };
+                        let sp = *self.arg_spans.get(self.curpiece).unwrap_or(&self.fmtsp);
                         let mut err = self.ecx.struct_span_err(sp, &msg[..]);
                         err.emit();
                     }
@@ -892,110 +886,20 @@ pub fn expand_preparsed_format_args(
         }
     };
 
-    let (is_literal, fmt_snippet) = match ecx.source_map().span_to_snippet(fmt_sp) {
-        Ok(s) => (s.starts_with('"') || s.starts_with("r#"), Some(s)),
-        _ => (false, None),
-    };
-
     let str_style = match fmt_style {
         ast::StrStyle::Cooked => None,
         ast::StrStyle::Raw(raw) => Some(raw as usize),
     };
 
-    /// Finds the indices of all characters that have been processed and differ between the actual
-    /// written code (code snippet) and the `InternedString` that gets processed in the `Parser`
-    /// in order to properly synthethise the intra-string `Span`s for error diagnostics.
-    fn find_skips(snippet: &str, is_raw: bool) -> Vec<usize> {
-        let mut eat_ws = false;
-        let mut s = snippet.chars().enumerate().peekable();
-        let mut skips = vec![];
-        while let Some((pos, c)) = s.next() {
-            match (c, s.peek()) {
-                // skip whitespace and empty lines ending in '\\'
-                ('\\', Some((next_pos, '\n'))) if !is_raw => {
-                    eat_ws = true;
-                    skips.push(pos);
-                    skips.push(*next_pos);
-                    let _ = s.next();
-                }
-                ('\\', Some((next_pos, '\n' | 'n' | 't'))) if eat_ws => {
-                    skips.push(pos);
-                    skips.push(*next_pos);
-                    let _ = s.next();
-                }
-                (' ' | '\n' | '\t', _) if eat_ws => {
-                    skips.push(pos);
-                }
-                ('\\', Some((next_pos, 'n' | 't' | '0' | '\\' | '\'' | '\"'))) => {
-                    skips.push(*next_pos);
-                    let _ = s.next();
-                }
-                ('\\', Some((_, 'x'))) if !is_raw => {
-                    for _ in 0..3 {
-                        // consume `\xAB` literal
-                        if let Some((pos, _)) = s.next() {
-                            skips.push(pos);
-                        } else {
-                            break;
-                        }
-                    }
-                }
-                ('\\', Some((_, 'u'))) if !is_raw => {
-                    if let Some((pos, _)) = s.next() {
-                        skips.push(pos);
-                    }
-                    if let Some((next_pos, next_c)) = s.next() {
-                        if next_c == '{' {
-                            skips.push(next_pos);
-                            let mut i = 0; // consume up to 6 hexanumeric chars + closing `}`
-                            while let (Some((next_pos, c)), true) = (s.next(), i < 7) {
-                                if c.is_digit(16) {
-                                    skips.push(next_pos);
-                                } else if c == '}' {
-                                    skips.push(next_pos);
-                                    break;
-                                } else {
-                                    break;
-                                }
-                                i += 1;
-                            }
-                        } else if next_c.is_digit(16) {
-                            skips.push(next_pos);
-                            // We suggest adding `{` and `}` when appropriate, accept it here as if
-                            // it were correct
-                            let mut i = 0; // consume up to 6 hexanumeric chars
-                            while let (Some((next_pos, c)), _) = (s.next(), i < 6) {
-                                if c.is_digit(16) {
-                                    skips.push(next_pos);
-                                } else {
-                                    break;
-                                }
-                                i += 1;
-                            }
-                        }
-                    }
-                }
-                _ if eat_ws => {
-                    // `take_while(|c| c.is_whitespace())`
-                    eat_ws = false;
-                }
-                _ => {}
-            }
-        }
-        skips
-    }
-
-    let skips = if let (true, Some(ref snippet)) = (is_literal, fmt_snippet.as_ref()) {
-        let r_start = str_style.map(|r| r + 1).unwrap_or(0);
-        let r_end = str_style.map(|r| r).unwrap_or(0);
-        let s = &snippet[r_start + 1..snippet.len() - r_end - 1];
-        find_skips(s, str_style.is_some())
-    } else {
-        vec![]
-    };
-
     let fmt_str = &fmt_str.as_str(); // for the suggestions below
-    let mut parser = parse::Parser::new(fmt_str, str_style, skips, append_newline);
+    let fmt_snippet = ecx.source_map().span_to_snippet(fmt_sp).ok();
+    let mut parser = parse::Parser::new(
+        fmt_str,
+        str_style,
+        fmt_snippet,
+        append_newline,
+        parse::ParseMode::Format,
+    );
 
     let mut unverified_pieces = Vec::new();
     while let Some(piece) = parser.next() {
@@ -1048,7 +952,6 @@ pub fn expand_preparsed_format_args(
         invalid_refs: Vec::new(),
         arg_spans,
         arg_with_formatting: Vec::new(),
-        is_literal,
     };
 
     // This needs to happen *after* the Parser has consumed all pieces to create all the spans