From 38abca8c2d7de08861cd61bc439efdb7cf4de398 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Sun, 22 Jul 2018 22:40:24 -0700 Subject: Point at internal span in format string --- src/libsyntax_ext/format.rs | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'src/libsyntax_ext') diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 755d2b476b7..4700f814e58 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -21,7 +21,7 @@ use syntax::feature_gate; use syntax::parse::token; use syntax::ptr::P; use syntax::symbol::Symbol; -use syntax_pos::{Span, DUMMY_SP}; +use syntax_pos::{Span, MultiSpan, DUMMY_SP}; use syntax::tokenstream; use std::collections::{HashMap, HashSet}; @@ -264,28 +264,38 @@ impl<'a, 'b> Context<'a, 'b> { /// errors for the case where all arguments are positional and for when /// there are named arguments or numbered positional arguments in the /// format string. - fn report_invalid_references(&self, numbered_position_args: bool) { + fn report_invalid_references(&self, numbered_position_args: bool, arg_places: &[(usize, usize)]) { let mut e; - let mut refs: Vec = self.invalid_refs - .iter() - .map(|r| r.to_string()) - .collect(); + let sps = arg_places.iter() + .map(|&(start, end)| self.fmtsp.from_inner_byte_pos(start, end)) + .collect::>(); + let sp = MultiSpan::from_spans(sps); + let mut refs: Vec<_> = self.invalid_refs + .iter() + .map(|r| r.to_string()) + .collect(); if self.names.is_empty() && !numbered_position_args { - e = self.ecx.mut_span_err(self.fmtsp, + e = self.ecx.mut_span_err(sp, &format!("{} positional argument{} in format string, but {}", self.pieces.len(), if self.pieces.len() > 1 { "s" } else { "" }, self.describe_num_args())); } else { let arg_list = match refs.len() { - 1 => format!("argument {}", refs.pop().unwrap()), - _ => format!("arguments {head} and {tail}", - tail=refs.pop().unwrap(), + 1 => { + let reg = refs.pop().unwrap(); + format!("argument {}", reg) + }, + _ => { + let reg = refs.pop().unwrap(); + format!("arguments {head} and {tail}", + tail=reg, head=refs.join(", ")) + } }; - e = self.ecx.mut_span_err(self.fmtsp, + e = self.ecx.mut_span_err(sp, &format!("invalid reference to positional {} ({})", arg_list, self.describe_num_args())); @@ -835,7 +845,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, } if cx.invalid_refs.len() >= 1 { - cx.report_invalid_references(numbered_position_args); + cx.report_invalid_references(numbered_position_args, &parser.arg_places); } // Make sure that all arguments were used and all arguments have types. -- cgit 1.4.1-3-g733a5