Skip to content

Commit d7191ec

Browse files
committed
warn on empty precision
1 parent ee361e8 commit d7191ec

File tree

4 files changed

+63
-7
lines changed

4 files changed

+63
-7
lines changed

compiler/rustc_builtin_macros/src/format.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -267,10 +267,9 @@ fn make_format_args(
267267

268268
let is_source_literal = parser.is_source_literal;
269269

270-
if !parser.errors.is_empty() {
271-
let err = parser.errors.remove(0);
272-
let sp = if is_source_literal {
273-
fmt_span.from_inner(InnerSpan::new(err.span.start, err.span.end))
270+
let snippetify = |span: &Range<usize>| {
271+
if is_source_literal {
272+
fmt_span.from_inner(InnerSpan::new(span.start, span.end))
274273
} else {
275274
// The format string could be another macro invocation, e.g.:
276275
// format!(concat!("abc", "{}"), 4);
@@ -281,9 +280,25 @@ fn make_format_args(
281280
// Therefore, we conservatively report the error for the entire
282281
// argument span here.
283282
fmt_span
283+
}
284+
};
285+
286+
for w in &parser.warnings {
287+
let warn = errors::InvalidFormatString {
288+
span: snippetify(&w.span),
289+
note_: w.note.clone().map(|note| errors::InvalidFormatStringNote { note }),
290+
label_: None,
291+
sugg_: None,
292+
desc: w.description.clone(),
293+
label1: w.label.clone(),
284294
};
295+
ecx.dcx().emit_warn(warn);
296+
}
297+
298+
if !parser.errors.is_empty() {
299+
let err = parser.errors.remove(0);
285300
let mut e = errors::InvalidFormatString {
286-
span: sp,
301+
span: snippetify(&err.span),
287302
note_: None,
288303
label_: None,
289304
sugg_: None,

compiler/rustc_parse_format/src/lib.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,8 @@ pub struct Parser<'input> {
204204
input_vec: Vec<(Range<usize>, usize, char)>,
205205
/// Index into input_vec
206206
input_vec_index: usize,
207+
/// Warnings accumulated during parsing
208+
pub warnings: Vec<ParseError>,
207209
/// Error messages accumulated during parsing
208210
pub errors: Vec<ParseError>,
209211
/// Current position of implicit positional argument pointer
@@ -379,6 +381,7 @@ impl<'input> Parser<'input> {
379381
input,
380382
input_vec,
381383
input_vec_index: 0,
384+
warnings: vec![],
382385
errors: vec![],
383386
curarg: 0,
384387
arg_places: vec![],
@@ -651,8 +654,20 @@ impl<'input> Parser<'input> {
651654
} else {
652655
spec.precision = self.count();
653656
}
654-
spec.precision_span =
655-
Some(range.start..self.input_vec_index2range(self.input_vec_index).start);
657+
let span = range.start..self.input_vec_index2range(self.input_vec_index).start;
658+
if spec.precision == CountImplied {
659+
self.warnings.push(ParseError {
660+
description: "expected numerical precision after precision specifier"
661+
.to_string(),
662+
note: Some("This may become an error in a future release".to_string()),
663+
label: "precision specifier without numerical precision".to_string(),
664+
span,
665+
secondary_label: None,
666+
suggestion: Suggestion::None,
667+
});
668+
} else {
669+
spec.precision_span = Some(span);
670+
}
656671
}
657672

658673
let start_idx = self.input_vec_index;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//@ run-pass
2+
fn main() {
3+
let float = 0.123_456_789;
4+
println!("Missing precisions: {float:.1} {float:.} {float:.3} {float:.}");
5+
//~^ WARNING invalid format string: expected numerical precision after precision specifier
6+
//~| WARNING invalid format string: expected numerical precision after precision specifier
7+
println!("Precision: {float:.1} {float:.9}");
8+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
warning: invalid format string: expected numerical precision after precision specifier
2+
--> $DIR/warn-on-empty-precision.rs:4:53
3+
|
4+
LL | println!("Missing precisions: {float:.1} {float:.} {float:.3} {float:.}");
5+
| ^ precision specifier without numerical precision in format string
6+
|
7+
= note: This may become an error in a future release
8+
9+
warning: invalid format string: expected numerical precision after precision specifier
10+
--> $DIR/warn-on-empty-precision.rs:4:74
11+
|
12+
LL | println!("Missing precisions: {float:.1} {float:.} {float:.3} {float:.}");
13+
| ^ precision specifier without numerical precision in format string
14+
|
15+
= note: This may become an error in a future release
16+
17+
warning: 2 warnings emitted
18+

0 commit comments

Comments
 (0)