Skip to content

Commit c733a02

Browse files
committedJan 8, 2024
Remove a fourth DiagnosticBuilder::emit_without_consuming call.
The old code was very hard to understand, involving an `emit_without_consuming` call *and* a `delay_as_bug_without_consuming` call. With slight changes both calls can be avoided. Not creating the error until later is crucial, as is the early return in the `if recovered` block. It took me some time to come up with this reworking -- it went through intermediate states much further from the original code than this final version -- and it's isn't obvious at a glance that it is equivalent. But I think it is, and the unchanged test behaviour is good supporting evidence. The commit also changes `check_trailing_angle_brackets` to return `Option<ErrorGuaranteed>`. This provides a stricter proof that it emitted an error message than asserting `dcx.has_errors().is_some()`, which would succeed if any error had previously been emitted anywhere.
1 parent 1b6c8e7 commit c733a02

File tree

2 files changed

+21
-31
lines changed

2 files changed

+21
-31
lines changed
 

Diff for: ‎compiler/rustc_parse/src/parser/diagnostics.rs

+8-9
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ use rustc_ast::{
3434
use rustc_ast_pretty::pprust;
3535
use rustc_data_structures::fx::FxHashSet;
3636
use rustc_errors::{
37-
pluralize, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, FatalError,
38-
PErr, PResult,
37+
pluralize, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder,
38+
ErrorGuaranteed, FatalError, PErr, PResult,
3939
};
4040
use rustc_session::errors::ExprParenthesesNeeded;
4141
use rustc_span::source_map::Spanned;
@@ -1049,9 +1049,9 @@ impl<'a> Parser<'a> {
10491049
&mut self,
10501050
segment: &PathSegment,
10511051
end: &[&TokenKind],
1052-
) -> bool {
1052+
) -> Option<ErrorGuaranteed> {
10531053
if !self.may_recover() {
1054-
return false;
1054+
return None;
10551055
}
10561056

10571057
// This function is intended to be invoked after parsing a path segment where there are two
@@ -1086,7 +1086,7 @@ impl<'a> Parser<'a> {
10861086
parsed_angle_bracket_args,
10871087
);
10881088
if !parsed_angle_bracket_args {
1089-
return false;
1089+
return None;
10901090
}
10911091

10921092
// Keep the span at the start so we can highlight the sequence of `>` characters to be
@@ -1124,7 +1124,7 @@ impl<'a> Parser<'a> {
11241124
number_of_gt, number_of_shr,
11251125
);
11261126
if number_of_gt < 1 && number_of_shr < 1 {
1127-
return false;
1127+
return None;
11281128
}
11291129

11301130
// Finally, double check that we have our end token as otherwise this is the
@@ -1139,10 +1139,9 @@ impl<'a> Parser<'a> {
11391139
let span = lo.until(self.token.span);
11401140

11411141
let num_extra_brackets = number_of_gt + number_of_shr * 2;
1142-
self.dcx().emit_err(UnmatchedAngleBrackets { span, num_extra_brackets });
1143-
return true;
1142+
return Some(self.dcx().emit_err(UnmatchedAngleBrackets { span, num_extra_brackets }));
11441143
}
1145-
false
1144+
None
11461145
}
11471146

11481147
/// Check if a method call with an intended turbofish has been written without surrounding

Diff for: ‎compiler/rustc_parse/src/parser/item.rs

+13-22
Original file line numberDiff line numberDiff line change
@@ -1793,52 +1793,43 @@ impl<'a> Parser<'a> {
17931793
}
17941794
_ => {
17951795
let sp = self.prev_token.span.shrink_to_hi();
1796-
let mut err = self.dcx().struct_span_err(
1797-
sp,
1798-
format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token)),
1799-
);
1796+
let msg =
1797+
format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token));
18001798

18011799
// Try to recover extra trailing angle brackets
1802-
let mut recovered = false;
18031800
if let TyKind::Path(_, Path { segments, .. }) = &a_var.ty.kind {
18041801
if let Some(last_segment) = segments.last() {
1805-
recovered = self.check_trailing_angle_brackets(
1802+
let guar = self.check_trailing_angle_brackets(
18061803
last_segment,
18071804
&[&token::Comma, &token::CloseDelim(Delimiter::Brace)],
18081805
);
1809-
if recovered {
1806+
if let Some(_guar) = guar {
18101807
// Handle a case like `Vec<u8>>,` where we can continue parsing fields
18111808
// after the comma
18121809
self.eat(&token::Comma);
1813-
// `check_trailing_angle_brackets` already emitted a nicer error
1814-
// NOTE(eddyb) this was `.cancel()`, but `err`
1815-
// gets returned, so we can't fully defuse it.
1816-
err.delay_as_bug_without_consuming();
1810+
1811+
// `check_trailing_angle_brackets` already emitted a nicer error, as
1812+
// proven by the presence of `_guar`. We can continue parsing.
1813+
return Ok(a_var);
18171814
}
18181815
}
18191816
}
18201817

1818+
let mut err = self.dcx().struct_span_err(sp, msg);
1819+
18211820
if self.token.is_ident()
18221821
|| (self.token.kind == TokenKind::Pound
18231822
&& (self.look_ahead(1, |t| t == &token::OpenDelim(Delimiter::Bracket))))
18241823
{
1825-
// This is likely another field, TokenKind::Pound is used for `#[..]` attribute for next field,
1826-
// emit the diagnostic and keep going
1824+
// This is likely another field, TokenKind::Pound is used for `#[..]`
1825+
// attribute for next field. Emit the diagnostic and continue parsing.
18271826
err.span_suggestion(
18281827
sp,
18291828
"try adding a comma",
18301829
",",
18311830
Applicability::MachineApplicable,
18321831
);
1833-
err.emit_without_consuming();
1834-
recovered = true;
1835-
}
1836-
1837-
if recovered {
1838-
// Make sure an error was emitted (either by recovering an angle bracket,
1839-
// or by finding an identifier as the next token), since we're
1840-
// going to continue parsing
1841-
assert!(self.dcx().has_errors().is_some());
1832+
err.emit();
18421833
} else {
18431834
return Err(err);
18441835
}

0 commit comments

Comments
 (0)