Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions compiler/rustc_builtin_macros/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,10 +267,9 @@ fn make_format_args(

let is_source_literal = parser.is_source_literal;

if !parser.errors.is_empty() {
let err = parser.errors.remove(0);
let sp = if is_source_literal {
fmt_span.from_inner(InnerSpan::new(err.span.start, err.span.end))
let snippetify = |span: &Range<usize>| {
if is_source_literal {
fmt_span.from_inner(InnerSpan::new(span.start, span.end))
} else {
// The format string could be another macro invocation, e.g.:
// format!(concat!("abc", "{}"), 4);
Expand All @@ -281,9 +280,25 @@ fn make_format_args(
// Therefore, we conservatively report the error for the entire
// argument span here.
fmt_span
}
};

for w in &parser.warnings {
let warn = errors::InvalidFormatString {
span: snippetify(&w.span),
note_: w.note.clone().map(|note| errors::InvalidFormatStringNote { note }),
label_: None,
sugg_: None,
desc: w.description.clone(),
label1: w.label.clone(),
};
ecx.dcx().emit_warn(warn);
}

if !parser.errors.is_empty() {
let err = parser.errors.remove(0);
let mut e = errors::InvalidFormatString {
span: sp,
span: snippetify(&err.span),
note_: None,
label_: None,
sugg_: None,
Expand Down
19 changes: 17 additions & 2 deletions compiler/rustc_parse_format/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ pub struct Parser<'input> {
input_vec: Vec<(Range<usize>, usize, char)>,
/// Index into input_vec
input_vec_index: usize,
/// Warnings accumulated during parsing
pub warnings: Vec<ParseError>,
/// Error messages accumulated during parsing
pub errors: Vec<ParseError>,
/// Current position of implicit positional argument pointer
Expand Down Expand Up @@ -379,6 +381,7 @@ impl<'input> Parser<'input> {
input,
input_vec,
input_vec_index: 0,
warnings: vec![],
errors: vec![],
curarg: 0,
arg_places: vec![],
Expand Down Expand Up @@ -651,8 +654,20 @@ impl<'input> Parser<'input> {
} else {
spec.precision = self.count();
}
spec.precision_span =
Some(range.start..self.input_vec_index2range(self.input_vec_index).start);
let span = range.start..self.input_vec_index2range(self.input_vec_index).start;
if spec.precision == CountImplied {
self.warnings.push(ParseError {
description: "expected numerical precision after precision specifier"
.to_string(),
note: Some("This may become an error in a future release".to_string()),
label: "precision specifier without numerical precision".to_string(),
span,
secondary_label: None,
suggestion: Suggestion::None,
});
} else {
spec.precision_span = Some(span);
}
}

let start_idx = self.input_vec_index;
Expand Down
9 changes: 9 additions & 0 deletions tests/ui/fmt/warn-on-empty-precision.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//@ run-pass
fn main() {
let float = 0.123_456_789;
println!("Missing precision: {float:.} {float:3.} {float:_^12.}");
//~^ WARNING invalid format string: expected numerical precision after precision specifier
//~| WARNING invalid format string: expected numerical precision after precision specifier
//~| WARNING invalid format string: expected numerical precision after precision specifier
println!("Given precision: {float:.6} {float:3.15} {float:_^12.7}");
}
26 changes: 26 additions & 0 deletions tests/ui/fmt/warn-on-empty-precision.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
warning: invalid format string: expected numerical precision after precision specifier
--> $DIR/warn-on-empty-precision.rs:4:41
|
LL | println!("Missing precision: {float:.} {float:3.} {float:_^12.}");
| ^ precision specifier without numerical precision in format string
|
= note: This may become an error in a future release

warning: invalid format string: expected numerical precision after precision specifier
--> $DIR/warn-on-empty-precision.rs:4:52
|
LL | println!("Missing precision: {float:.} {float:3.} {float:_^12.}");
| ^ precision specifier without numerical precision in format string
|
= note: This may become an error in a future release

warning: invalid format string: expected numerical precision after precision specifier
--> $DIR/warn-on-empty-precision.rs:4:66
|
LL | println!("Missing precision: {float:.} {float:3.} {float:_^12.}");
| ^ precision specifier without numerical precision in format string
|
= note: This may become an error in a future release

warning: 3 warnings emitted

Loading