summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorChayim Refael Friedman <chayimfr@gmail.com>2022-02-16 00:38:04 +0000
committerGitHub <noreply@github.com>2022-02-16 07:34:06 +0000
commit91adb6ccd693737aaf740bc18bc6f82e3898d322 (patch)
treeac02a2e2a47eae34e20200b947efa94da3321b20 /compiler
parent1e12aef3fab243407f9d71ba9956cb2a1bf105d5 (diff)
downloadrust-91adb6ccd693737aaf740bc18bc6f82e3898d322.tar.gz
Correctly mark the span of captured arguments in `format_args!()`
It should only include the identifier, or misspelling suggestions will be wrong.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs26
-rw-r--r--compiler/rustc_parse_format/src/lib.rs16
-rw-r--r--compiler/rustc_parse_format/src/tests.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/on_unimplemented.rs16
5 files changed, 35 insertions, 31 deletions
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 1a6e5694791..ac37c4973d8 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -700,11 +700,11 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
Some(idx)
}
}
- parse::ArgumentNamed(name) => match args.named_args.get(&name) {
+ parse::ArgumentNamed(name, span) => match args.named_args.get(&name) {
Some(&idx) => Some(idx),
None => {
let msg = format!("there is no argument named `{}`", name);
- ecx.struct_span_err(span, &msg).emit();
+ ecx.struct_span_err(template_span.from_inner(span), &msg).emit();
None
}
},
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 584fbd1b605..6141d00f697 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -11,7 +11,7 @@ use rustc_errors::{pluralize, Applicability, DiagnosticBuilder};
use rustc_expand::base::{self, *};
use rustc_parse_format as parse;
use rustc_span::symbol::{sym, Ident, Symbol};
-use rustc_span::{MultiSpan, Span};
+use rustc_span::{InnerSpan, MultiSpan, Span};
use smallvec::SmallVec;
use std::borrow::Cow;
@@ -26,7 +26,7 @@ enum ArgumentType {
enum Position {
Exact(usize),
Capture(usize),
- Named(Symbol),
+ Named(Symbol, InnerSpan),
}
struct Context<'a, 'b> {
@@ -247,13 +247,13 @@ impl<'a, 'b> Context<'a, 'b> {
match *p {
parse::String(_) => {}
parse::NextArgument(ref mut arg) => {
- if let parse::ArgumentNamed(s) = arg.position {
+ if let parse::ArgumentNamed(s, _) = arg.position {
arg.position = parse::ArgumentIs(lookup(s));
}
- if let parse::CountIsName(s) = arg.format.width {
+ if let parse::CountIsName(s, _) = arg.format.width {
arg.format.width = parse::CountIsParam(lookup(s));
}
- if let parse::CountIsName(s) = arg.format.precision {
+ if let parse::CountIsName(s, _) = arg.format.precision {
arg.format.precision = parse::CountIsParam(lookup(s));
}
}
@@ -276,7 +276,7 @@ impl<'a, 'b> Context<'a, 'b> {
// it's written second, so it should come after width/precision.
let pos = match arg.position {
parse::ArgumentIs(i) | parse::ArgumentImplicitlyIs(i) => Exact(i),
- parse::ArgumentNamed(s) => Named(s),
+ parse::ArgumentNamed(s, span) => Named(s, span),
};
let ty = Placeholder(match arg.format.ty {
@@ -346,8 +346,8 @@ impl<'a, 'b> Context<'a, 'b> {
parse::CountIsParam(i) => {
self.verify_arg_type(Exact(i), Count);
}
- parse::CountIsName(s) => {
- self.verify_arg_type(Named(s), Count);
+ parse::CountIsName(s, span) => {
+ self.verify_arg_type(Named(s, span), Count);
}
}
}
@@ -533,7 +533,7 @@ impl<'a, 'b> Context<'a, 'b> {
}
}
- Named(name) => {
+ Named(name, span) => {
match self.names.get(&name) {
Some(&idx) => {
// Treat as positional arg.
@@ -548,7 +548,7 @@ impl<'a, 'b> Context<'a, 'b> {
self.arg_types.push(Vec::new());
self.arg_unique_types.push(Vec::new());
let span = if self.is_literal {
- *self.arg_spans.get(self.curpiece).unwrap_or(&self.fmtsp)
+ self.fmtsp.from_inner(span)
} else {
self.fmtsp
};
@@ -559,7 +559,7 @@ impl<'a, 'b> Context<'a, 'b> {
} else {
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)
+ self.fmtsp.from_inner(span)
} else {
self.fmtsp
};
@@ -629,7 +629,7 @@ impl<'a, 'b> Context<'a, 'b> {
}
parse::CountImplied => count(sym::Implied, None),
// should never be the case, names are already resolved
- parse::CountIsName(_) => panic!("should never happen"),
+ parse::CountIsName(..) => panic!("should never happen"),
}
}
@@ -676,7 +676,7 @@ impl<'a, 'b> Context<'a, 'b> {
// should never be the case, because names are already
// resolved.
- parse::ArgumentNamed(_) => panic!("should never happen"),
+ parse::ArgumentNamed(..) => panic!("should never happen"),
}
};
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index 9d653de910f..a6a2cbc277c 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -95,7 +95,7 @@ pub enum Position {
/// The argument is located at a specific index given in the format
ArgumentIs(usize),
/// The argument has a name.
- ArgumentNamed(Symbol),
+ ArgumentNamed(Symbol, InnerSpan),
}
impl Position {
@@ -147,7 +147,7 @@ pub enum Count {
/// The count is specified explicitly.
CountIs(usize),
/// The count is specified by the argument with the given name.
- CountIsName(Symbol),
+ CountIsName(Symbol, InnerSpan),
/// The count is specified by the argument at the given index.
CountIsParam(usize),
/// The count is implied and cannot be explicitly specified.
@@ -494,8 +494,11 @@ impl<'a> Parser<'a> {
Some(ArgumentIs(i))
} else {
match self.cur.peek() {
- Some(&(_, c)) if rustc_lexer::is_id_start(c) => {
- Some(ArgumentNamed(Symbol::intern(self.word())))
+ Some(&(start, c)) if rustc_lexer::is_id_start(c) => {
+ let word = self.word();
+ let end = start + word.len();
+ let span = self.to_span_index(start).to(self.to_span_index(end));
+ Some(ArgumentNamed(Symbol::intern(word), span))
}
// This is an `ArgumentNext`.
@@ -662,8 +665,9 @@ impl<'a> Parser<'a> {
if word.is_empty() {
self.cur = tmp;
(CountImplied, None)
- } else if self.consume('$') {
- (CountIsName(Symbol::intern(word)), None)
+ } else if let Some(end) = self.consume_pos('$') {
+ let span = self.to_span_index(start + 1).to(self.to_span_index(end));
+ (CountIsName(Symbol::intern(word), span), None)
} else {
self.cur = tmp;
(CountImplied, None)
diff --git a/compiler/rustc_parse_format/src/tests.rs b/compiler/rustc_parse_format/src/tests.rs
index b7693a85ad9..6c960fdc72b 100644
--- a/compiler/rustc_parse_format/src/tests.rs
+++ b/compiler/rustc_parse_format/src/tests.rs
@@ -221,8 +221,8 @@ fn format_counts() {
fill: None,
align: AlignUnknown,
flags: 0,
- precision: CountIsName(Symbol::intern("b")),
- width: CountIsName(Symbol::intern("a")),
+ precision: CountIsName(Symbol::intern("b"), InnerSpan::new(6, 7)),
+ width: CountIsName(Symbol::intern("a"), InnerSpan::new(4, 4)),
precision_span: None,
width_span: None,
ty: "?",
diff --git a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
index bdf677a63b6..b05dbbe898a 100644
--- a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
@@ -309,23 +309,23 @@ impl<'tcx> OnUnimplementedFormatString {
Piece::String(_) => (), // Normal string, no need to check it
Piece::NextArgument(a) => match a.position {
// `{Self}` is allowed
- Position::ArgumentNamed(s) if s == kw::SelfUpper => (),
+ Position::ArgumentNamed(s, _) if s == kw::SelfUpper => (),
// `{ThisTraitsName}` is allowed
- Position::ArgumentNamed(s) if s == name => (),
+ Position::ArgumentNamed(s, _) if s == name => (),
// `{from_method}` is allowed
- Position::ArgumentNamed(s) if s == sym::from_method => (),
+ Position::ArgumentNamed(s, _) if s == sym::from_method => (),
// `{from_desugaring}` is allowed
- Position::ArgumentNamed(s) if s == sym::from_desugaring => (),
+ Position::ArgumentNamed(s, _) if s == sym::from_desugaring => (),
// `{ItemContext}` is allowed
- Position::ArgumentNamed(s) if s == sym::ItemContext => (),
+ Position::ArgumentNamed(s, _) if s == sym::ItemContext => (),
// `{integral}` and `{integer}` and `{float}` are allowed
- Position::ArgumentNamed(s)
+ Position::ArgumentNamed(s, _)
if s == sym::integral || s == sym::integer_ || s == sym::float =>
{
()
}
// So is `{A}` if A is a type parameter
- Position::ArgumentNamed(s) => {
+ Position::ArgumentNamed(s, _) => {
match generics.params.iter().find(|param| param.name == s) {
Some(_) => (),
None => {
@@ -392,7 +392,7 @@ impl<'tcx> OnUnimplementedFormatString {
.map(|p| match p {
Piece::String(s) => s,
Piece::NextArgument(a) => match a.position {
- Position::ArgumentNamed(s) => match generic_map.get(&s) {
+ Position::ArgumentNamed(s, _) => match generic_map.get(&s) {
Some(val) => val,
None if s == name => &trait_str,
None => {