Skip to content

Commit f002aba

Browse files
committed
change FormatString::parse to only return the first error
1 parent b68c06b commit f002aba

File tree

4 files changed

+40
-68
lines changed

4 files changed

+40
-68
lines changed

compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -848,34 +848,27 @@ impl<'tcx> OnUnimplementedFormatString {
848848
}
849849
}
850850
}
851-
// Errors from the underlying `rustc_parse_format::Parser`
852-
Err(errors) => {
851+
// Error from the underlying `rustc_parse_format::Parser`
852+
Err(e) => {
853853
// we cannot return errors from processing the format string as hard error here
854854
// as the diagnostic namespace guarantees that malformed input cannot cause an error
855855
//
856856
// if we encounter any error while processing we nevertheless want to show it as warning
857857
// so that users are aware that something is not correct
858-
for e in errors {
859-
if self.is_diagnostic_namespace_variant {
860-
if let Some(trait_def_id) = trait_def_id.as_local() {
861-
tcx.emit_node_span_lint(
862-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
863-
tcx.local_def_id_to_hir_id(trait_def_id),
864-
self.span,
865-
WrappedParserError { description: e.description, label: e.label },
866-
);
867-
}
868-
} else {
869-
let reported = struct_span_code_err!(
870-
tcx.dcx(),
858+
if self.is_diagnostic_namespace_variant {
859+
if let Some(trait_def_id) = trait_def_id.as_local() {
860+
tcx.emit_node_span_lint(
861+
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
862+
tcx.local_def_id_to_hir_id(trait_def_id),
871863
self.span,
872-
E0231,
873-
"{}",
874-
e.description,
875-
)
876-
.emit();
877-
result = Err(reported);
864+
WrappedParserError { description: e.description, label: e.label },
865+
);
878866
}
867+
} else {
868+
let reported =
869+
struct_span_code_err!(tcx.dcx(), self.span, E0231, "{}", e.description,)
870+
.emit();
871+
result = Err(reported);
879872
}
880873
}
881874
}

compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -158,34 +158,29 @@ impl FormatString {
158158
self.span
159159
}
160160

161-
pub fn parse<'tcx>(
162-
input: Symbol,
163-
span: Span,
164-
ctx: &Ctx<'tcx>,
165-
) -> Result<Self, Vec<ParseError>> {
161+
pub fn parse<'tcx>(input: Symbol, span: Span, ctx: &Ctx<'tcx>) -> Result<Self, ParseError> {
166162
let s = input.as_str();
167163
let mut parser = Parser::new(s, None, None, false, ParseMode::Format);
168-
let mut pieces = Vec::new();
164+
let pieces: Vec<_> = parser.by_ref().collect();
165+
166+
if let Some(err) = parser.errors.into_iter().next() {
167+
return Err(err);
168+
}
169169
let mut warnings = Vec::new();
170170

171-
for piece in &mut parser {
172-
match piece {
173-
RpfPiece::Lit(lit) => {
174-
pieces.push(Piece::Lit(lit.into()));
175-
}
171+
let pieces = pieces
172+
.into_iter()
173+
.map(|piece| match piece {
174+
RpfPiece::Lit(lit) => Piece::Lit(lit.into()),
176175
RpfPiece::NextArgument(arg) => {
177176
warn_on_format_spec(arg.format.clone(), &mut warnings, span);
178177
let arg = parse_arg(&arg, ctx, &mut warnings, span);
179-
pieces.push(Piece::Arg(arg));
178+
Piece::Arg(arg)
180179
}
181-
}
182-
}
180+
})
181+
.collect();
183182

184-
if parser.errors.is_empty() {
185-
Ok(FormatString { input, pieces, span, warnings })
186-
} else {
187-
Err(parser.errors)
188-
}
183+
Ok(FormatString { input, pieces, span, warnings })
189184
}
190185

191186
pub fn format(&self, args: &FormatArgs<'_>) -> String {

tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ trait ImportantTrait4 {}
2222
#[diagnostic::on_unimplemented(message = "Test {Self:!}")]
2323
//~^WARN expected `}`, found `!`
2424
//~|WARN expected `}`, found `!`
25-
//~|WARN unmatched `}` found
26-
//~|WARN unmatched `}` found
2725
trait ImportantTrait5 {}
2826

2927
fn check_1(_: impl ImportantTrait1) {}

tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,6 @@ warning: expected `}`, found `!`
3636
LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")]
3737
| ^^^^^^^^^^^^^^^
3838

39-
warning: unmatched `}` found
40-
--> $DIR/broken_format.rs:22:42
41-
|
42-
LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")]
43-
| ^^^^^^^^^^^^^^^
44-
4539
warning: unmatched `}` found
4640
--> $DIR/broken_format.rs:2:42
4741
|
@@ -51,7 +45,7 @@ LL | #[diagnostic::on_unimplemented(message = "{{Test } thing")]
5145
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
5246

5347
error[E0277]: {{Test } thing
54-
--> $DIR/broken_format.rs:36:13
48+
--> $DIR/broken_format.rs:34:13
5549
|
5650
LL | check_1(());
5751
| ------- ^^ the trait `ImportantTrait1` is not implemented for `()`
@@ -64,7 +58,7 @@ help: this trait has no implementations, consider adding one
6458
LL | trait ImportantTrait1 {}
6559
| ^^^^^^^^^^^^^^^^^^^^^
6660
note: required by a bound in `check_1`
67-
--> $DIR/broken_format.rs:29:20
61+
--> $DIR/broken_format.rs:27:20
6862
|
6963
LL | fn check_1(_: impl ImportantTrait1) {}
7064
| ^^^^^^^^^^^^^^^ required by this bound in `check_1`
@@ -79,7 +73,7 @@ LL | #[diagnostic::on_unimplemented(message = "Test {}")]
7973
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
8074

8175
error[E0277]: Test {}
82-
--> $DIR/broken_format.rs:38:13
76+
--> $DIR/broken_format.rs:36:13
8377
|
8478
LL | check_2(());
8579
| ------- ^^ the trait `ImportantTrait2` is not implemented for `()`
@@ -92,7 +86,7 @@ help: this trait has no implementations, consider adding one
9286
LL | trait ImportantTrait2 {}
9387
| ^^^^^^^^^^^^^^^^^^^^^
9488
note: required by a bound in `check_2`
95-
--> $DIR/broken_format.rs:30:20
89+
--> $DIR/broken_format.rs:28:20
9690
|
9791
LL | fn check_2(_: impl ImportantTrait2) {}
9892
| ^^^^^^^^^^^^^^^ required by this bound in `check_2`
@@ -107,7 +101,7 @@ LL | #[diagnostic::on_unimplemented(message = "Test {1:}")]
107101
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
108102

109103
error[E0277]: Test {1}
110-
--> $DIR/broken_format.rs:40:13
104+
--> $DIR/broken_format.rs:38:13
111105
|
112106
LL | check_3(());
113107
| ------- ^^ the trait `ImportantTrait3` is not implemented for `()`
@@ -120,7 +114,7 @@ help: this trait has no implementations, consider adding one
120114
LL | trait ImportantTrait3 {}
121115
| ^^^^^^^^^^^^^^^^^^^^^
122116
note: required by a bound in `check_3`
123-
--> $DIR/broken_format.rs:31:20
117+
--> $DIR/broken_format.rs:29:20
124118
|
125119
LL | fn check_3(_: impl ImportantTrait3) {}
126120
| ^^^^^^^^^^^^^^^ required by this bound in `check_3`
@@ -135,7 +129,7 @@ LL | #[diagnostic::on_unimplemented(message = "Test {Self:123}")]
135129
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
136130

137131
error[E0277]: Test ()
138-
--> $DIR/broken_format.rs:42:13
132+
--> $DIR/broken_format.rs:40:13
139133
|
140134
LL | check_4(());
141135
| ------- ^^ the trait `ImportantTrait4` is not implemented for `()`
@@ -148,7 +142,7 @@ help: this trait has no implementations, consider adding one
148142
LL | trait ImportantTrait4 {}
149143
| ^^^^^^^^^^^^^^^^^^^^^
150144
note: required by a bound in `check_4`
151-
--> $DIR/broken_format.rs:32:20
145+
--> $DIR/broken_format.rs:30:20
152146
|
153147
LL | fn check_4(_: impl ImportantTrait4) {}
154148
| ^^^^^^^^^^^^^^^ required by this bound in `check_4`
@@ -161,33 +155,25 @@ LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")]
161155
|
162156
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
163157

164-
warning: unmatched `}` found
165-
--> $DIR/broken_format.rs:22:42
166-
|
167-
LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")]
168-
| ^^^^^^^^^^^^^^^
169-
|
170-
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
171-
172158
error[E0277]: Test {Self:!}
173-
--> $DIR/broken_format.rs:44:13
159+
--> $DIR/broken_format.rs:42:13
174160
|
175161
LL | check_5(());
176162
| ------- ^^ the trait `ImportantTrait5` is not implemented for `()`
177163
| |
178164
| required by a bound introduced by this call
179165
|
180166
help: this trait has no implementations, consider adding one
181-
--> $DIR/broken_format.rs:27:1
167+
--> $DIR/broken_format.rs:25:1
182168
|
183169
LL | trait ImportantTrait5 {}
184170
| ^^^^^^^^^^^^^^^^^^^^^
185171
note: required by a bound in `check_5`
186-
--> $DIR/broken_format.rs:33:20
172+
--> $DIR/broken_format.rs:31:20
187173
|
188174
LL | fn check_5(_: impl ImportantTrait5) {}
189175
| ^^^^^^^^^^^^^^^ required by this bound in `check_5`
190176

191-
error: aborting due to 5 previous errors; 12 warnings emitted
177+
error: aborting due to 5 previous errors; 10 warnings emitted
192178

193179
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)