Skip to content

Commit 35bf7f8

Browse files
authored
Rollup merge of rust-lang#47481 - estebank:unused-args, r=arielb1
Point at unused arguments for format string Avoid overlapping spans by only pointing at the arguments that are not being used in the argument string. Enable libsyntax to have diagnostics with multiple primary spans by accepting `Into<MultiSpan>` instead of `Span`. Partially addresses rust-lang#41850.
2 parents b2c5484 + eb3da09 commit 35bf7f8

File tree

7 files changed

+69
-77
lines changed

7 files changed

+69
-77
lines changed

src/libsyntax/ext/base.rs

+19-19
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub use self::SyntaxExtension::*;
1313
use ast::{self, Attribute, Name, PatKind, MetaItem};
1414
use attr::HasAttrs;
1515
use codemap::{self, CodeMap, Spanned, respan};
16-
use syntax_pos::{Span, DUMMY_SP};
16+
use syntax_pos::{Span, MultiSpan, DUMMY_SP};
1717
use errors::DiagnosticBuilder;
1818
use ext::expand::{self, Expansion, Invocation};
1919
use ext::hygiene::{Mark, SyntaxContext};
@@ -754,22 +754,22 @@ impl<'a> ExtCtxt<'a> {
754754
last_macro
755755
}
756756

757-
pub fn struct_span_warn(&self,
758-
sp: Span,
759-
msg: &str)
760-
-> DiagnosticBuilder<'a> {
757+
pub fn struct_span_warn<S: Into<MultiSpan>>(&self,
758+
sp: S,
759+
msg: &str)
760+
-> DiagnosticBuilder<'a> {
761761
self.parse_sess.span_diagnostic.struct_span_warn(sp, msg)
762762
}
763-
pub fn struct_span_err(&self,
764-
sp: Span,
765-
msg: &str)
766-
-> DiagnosticBuilder<'a> {
763+
pub fn struct_span_err<S: Into<MultiSpan>>(&self,
764+
sp: S,
765+
msg: &str)
766+
-> DiagnosticBuilder<'a> {
767767
self.parse_sess.span_diagnostic.struct_span_err(sp, msg)
768768
}
769-
pub fn struct_span_fatal(&self,
770-
sp: Span,
771-
msg: &str)
772-
-> DiagnosticBuilder<'a> {
769+
pub fn struct_span_fatal<S: Into<MultiSpan>>(&self,
770+
sp: S,
771+
msg: &str)
772+
-> DiagnosticBuilder<'a> {
773773
self.parse_sess.span_diagnostic.struct_span_fatal(sp, msg)
774774
}
775775

@@ -785,7 +785,7 @@ impl<'a> ExtCtxt<'a> {
785785
/// in most cases one can construct a dummy expression/item to
786786
/// substitute; we never hit resolve/type-checking so the dummy
787787
/// value doesn't have to match anything)
788-
pub fn span_fatal(&self, sp: Span, msg: &str) -> ! {
788+
pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
789789
panic!(self.parse_sess.span_diagnostic.span_fatal(sp, msg));
790790
}
791791

@@ -794,20 +794,20 @@ impl<'a> ExtCtxt<'a> {
794794
///
795795
/// Compilation will be stopped in the near future (at the end of
796796
/// the macro expansion phase).
797-
pub fn span_err(&self, sp: Span, msg: &str) {
797+
pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
798798
self.parse_sess.span_diagnostic.span_err(sp, msg);
799799
}
800-
pub fn mut_span_err(&self, sp: Span, msg: &str)
800+
pub fn mut_span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str)
801801
-> DiagnosticBuilder<'a> {
802802
self.parse_sess.span_diagnostic.mut_span_err(sp, msg)
803803
}
804-
pub fn span_warn(&self, sp: Span, msg: &str) {
804+
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
805805
self.parse_sess.span_diagnostic.span_warn(sp, msg);
806806
}
807-
pub fn span_unimpl(&self, sp: Span, msg: &str) -> ! {
807+
pub fn span_unimpl<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
808808
self.parse_sess.span_diagnostic.span_unimpl(sp, msg);
809809
}
810-
pub fn span_bug(&self, sp: Span, msg: &str) -> ! {
810+
pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
811811
self.parse_sess.span_diagnostic.span_bug(sp, msg);
812812
}
813813
pub fn trace_macros_diag(&mut self) {

src/libsyntax/parse/parser.rs

+15-10
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use ast::{BinOpKind, UnOp};
4242
use ast::{RangeEnd, RangeSyntax};
4343
use {ast, attr};
4444
use codemap::{self, CodeMap, Spanned, respan};
45-
use syntax_pos::{self, Span, BytePos, FileName, DUMMY_SP};
45+
use syntax_pos::{self, Span, MultiSpan, BytePos, FileName, DUMMY_SP};
4646
use errors::{self, DiagnosticBuilder};
4747
use parse::{self, classify, token};
4848
use parse::common::SeqSep;
@@ -447,7 +447,9 @@ pub enum Error {
447447
}
448448

449449
impl Error {
450-
pub fn span_err(self, sp: Span, handler: &errors::Handler) -> DiagnosticBuilder {
450+
pub fn span_err<S: Into<MultiSpan>>(self,
451+
sp: S,
452+
handler: &errors::Handler) -> DiagnosticBuilder {
451453
match self {
452454
Error::FileNotFoundForModule { ref mod_name,
453455
ref default_path,
@@ -1266,13 +1268,16 @@ impl<'a> Parser<'a> {
12661268
pub fn fatal(&self, m: &str) -> DiagnosticBuilder<'a> {
12671269
self.sess.span_diagnostic.struct_span_fatal(self.span, m)
12681270
}
1269-
pub fn span_fatal(&self, sp: Span, m: &str) -> DiagnosticBuilder<'a> {
1271+
pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
12701272
self.sess.span_diagnostic.struct_span_fatal(sp, m)
12711273
}
1272-
pub fn span_fatal_err(&self, sp: Span, err: Error) -> DiagnosticBuilder<'a> {
1274+
pub fn span_fatal_err<S: Into<MultiSpan>>(&self, sp: S, err: Error) -> DiagnosticBuilder<'a> {
12731275
err.span_err(sp, self.diagnostic())
12741276
}
1275-
pub fn span_fatal_help(&self, sp: Span, m: &str, help: &str) -> DiagnosticBuilder<'a> {
1277+
pub fn span_fatal_help<S: Into<MultiSpan>>(&self,
1278+
sp: S,
1279+
m: &str,
1280+
help: &str) -> DiagnosticBuilder<'a> {
12761281
let mut err = self.sess.span_diagnostic.struct_span_fatal(sp, m);
12771282
err.help(help);
12781283
err
@@ -1283,21 +1288,21 @@ impl<'a> Parser<'a> {
12831288
pub fn warn(&self, m: &str) {
12841289
self.sess.span_diagnostic.span_warn(self.span, m)
12851290
}
1286-
pub fn span_warn(&self, sp: Span, m: &str) {
1291+
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, m: &str) {
12871292
self.sess.span_diagnostic.span_warn(sp, m)
12881293
}
1289-
pub fn span_err(&self, sp: Span, m: &str) {
1294+
pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) {
12901295
self.sess.span_diagnostic.span_err(sp, m)
12911296
}
1292-
pub fn struct_span_err(&self, sp: Span, m: &str) -> DiagnosticBuilder<'a> {
1297+
pub fn struct_span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
12931298
self.sess.span_diagnostic.struct_span_err(sp, m)
12941299
}
1295-
pub fn span_err_help(&self, sp: Span, m: &str, h: &str) {
1300+
pub fn span_err_help<S: Into<MultiSpan>>(&self, sp: S, m: &str, h: &str) {
12961301
let mut err = self.sess.span_diagnostic.mut_span_err(sp, m);
12971302
err.help(h);
12981303
err.emit();
12991304
}
1300-
pub fn span_bug(&self, sp: Span, m: &str) -> ! {
1305+
pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> ! {
13011306
self.sess.span_diagnostic.span_bug(sp, m)
13021307
}
13031308
pub fn abort_if_errors(&self) {

src/libsyntax_ext/format.rs

+5-9
Original file line numberDiff line numberDiff line change
@@ -814,15 +814,11 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
814814
let (sp, msg) = errs.into_iter().next().unwrap();
815815
cx.ecx.struct_span_err(sp, msg)
816816
} else {
817-
let mut diag = cx.ecx.struct_span_err(cx.fmtsp,
818-
"multiple unused formatting arguments");
819-
820-
// Ignoring message, as it gets repetitive
821-
// Then use MultiSpan to not clutter up errors
822-
for (sp, _) in errs {
823-
diag.span_label(sp, "unused");
824-
}
825-
817+
let mut diag = cx.ecx.struct_span_err(
818+
errs.iter().map(|&(sp, _)| sp).collect::<Vec<Span>>(),
819+
"multiple unused formatting arguments"
820+
);
821+
diag.span_label(cx.fmtsp, "multiple unused arguments in this statement");
826822
diag
827823
}
828824
};

src/test/ui/macros/format-foreign.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// except according to those terms.
1010

1111
fn main() {
12-
println!("%.*3$s %s!\n", "Hello,", "World", 4);
12+
println!("%.*3$s %s!\n", "Hello,", "World", 4); //~ ERROR multiple unused formatting arguments
1313
println!("%1$*2$.*3$f", 123.456); //~ ERROR never used
1414

1515
// This should *not* produce hints, on the basis that there's equally as

src/test/ui/macros/format-foreign.stderr

+3-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
error: multiple unused formatting arguments
2-
--> $DIR/format-foreign.rs:12:5
2+
--> $DIR/format-foreign.rs:12:30
33
|
4-
12 | println!("%.*3$s %s!/n", "Hello,", "World", 4);
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^--------^^-------^^-^^
6-
| | | |
7-
| | | unused
8-
| | unused
9-
| unused
4+
12 | println!("%.*3$s %s!/n", "Hello,", "World", 4); //~ ERROR multiple unused formatting arguments
5+
| -------------------------^^^^^^^^--^^^^^^^--^-- multiple unused arguments in this statement
106
|
117
= help: `%.*3$s` should be written as `{:.2$}`
128
= help: `%s` should be written as `{}`

src/test/ui/macros/format-unused-lables.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,18 @@
1010

1111
fn main() {
1212
println!("Test", 123, 456, 789);
13+
//~^ ERROR multiple unused formatting arguments
1314

1415
println!("Test2",
15-
123,
16+
123, //~ ERROR multiple unused formatting arguments
1617
456,
1718
789
1819
);
1920

2021
println!("Some stuff", UNUSED="args"); //~ ERROR named argument never used
2122

2223
println!("Some more $STUFF",
23-
"woo!",
24+
"woo!", //~ ERROR multiple unused formatting arguments
2425
STUFF=
2526
"things"
2627
, UNUSED="args");

src/test/ui/macros/format-unused-lables.stderr

+23-29
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,43 @@
11
error: multiple unused formatting arguments
2-
--> $DIR/format-unused-lables.rs:12:5
2+
--> $DIR/format-unused-lables.rs:12:22
33
|
44
12 | println!("Test", 123, 456, 789);
5-
| ^^^^^^^^^^^^^^^^^---^^---^^---^^
6-
| | | |
7-
| | | unused
8-
| | unused
9-
| unused
5+
| -----------------^^^--^^^--^^^-- multiple unused arguments in this statement
106
|
117
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
128

139
error: multiple unused formatting arguments
14-
--> $DIR/format-unused-lables.rs:14:5
10+
--> $DIR/format-unused-lables.rs:16:9
1511
|
16-
14 | / println!("Test2",
17-
15 | | 123,
18-
| | --- unused
19-
16 | | 456,
20-
| | --- unused
21-
17 | | 789
22-
| | --- unused
23-
18 | | );
24-
| |______^
12+
15 | / println!("Test2",
13+
16 | | 123, //~ ERROR multiple unused formatting arguments
14+
| | ^^^
15+
17 | | 456,
16+
| | ^^^
17+
18 | | 789
18+
| | ^^^
19+
19 | | );
20+
| |______- multiple unused arguments in this statement
2521
|
2622
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
2723

2824
error: named argument never used
29-
--> $DIR/format-unused-lables.rs:20:35
25+
--> $DIR/format-unused-lables.rs:21:35
3026
|
31-
20 | println!("Some stuff", UNUSED="args"); //~ ERROR named argument never used
27+
21 | println!("Some stuff", UNUSED="args"); //~ ERROR named argument never used
3228
| ^^^^^^
3329

3430
error: multiple unused formatting arguments
35-
--> $DIR/format-unused-lables.rs:22:5
31+
--> $DIR/format-unused-lables.rs:24:9
3632
|
37-
22 | / println!("Some more $STUFF",
38-
23 | | "woo!",
39-
| | ------ unused
40-
24 | | STUFF=
41-
25 | | "things"
42-
| | -------- unused
43-
26 | | , UNUSED="args");
44-
| |_______________________------_^
45-
| |
46-
| unused
33+
23 | / println!("Some more $STUFF",
34+
24 | | "woo!", //~ ERROR multiple unused formatting arguments
35+
| | ^^^^^^
36+
25 | | STUFF=
37+
26 | | "things"
38+
| | ^^^^^^^^
39+
27 | | , UNUSED="args");
40+
| |_______________________^^^^^^_- multiple unused arguments in this statement
4741
|
4842
= help: `$STUFF` should be written as `{STUFF}`
4943
= note: shell formatting not supported; see the documentation for `std::fmt`

0 commit comments

Comments
 (0)