diff options
| author | Matthias Krüger <476013+matthiaskrgr@users.noreply.github.com> | 2025-03-19 16:52:56 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-19 16:52:56 +0100 |
| commit | c3f74bcb39849b10c8b336db18530c79d7cb8701 (patch) | |
| tree | e50da18a5ccf7863256fc0f876ae75b55b7db1ee /compiler/rustc_parse/src/parser/diagnostics.rs | |
| parent | 2df731d586319ec9a90676fcf7eca43ca60825c5 (diff) | |
| parent | f478853f425fc0207add653b48c49c937acaa94e (diff) | |
| download | rust-c3f74bcb39849b10c8b336db18530c79d7cb8701.tar.gz rust-c3f74bcb39849b10c8b336db18530c79d7cb8701.zip | |
Rollup merge of #138589 - zachs18:block-label-not-supported-here-loop-body-help, r=petrochenkov
If a label is placed on the block of a loop instead of the header, suggest moving it to the header.
Fixes #138585
If a label is placed on the block of a loop instead of the header, suggest to the user moving it to the loop header instead of ~~suggesting to remove it~~ emitting a tool-only suggestion to remove it.
```rs
fn main() {
loop 'a: { return; }
}
```
```diff
error: block label not supported here
--> src/main.rs:2:10
|
2 | loop 'a: { return; }
| ^^^ not supported here
+ |
+help: if you meant to label the loop, move this label before the loop
+ |
+2 - loop 'a: { return; }
+2 + 'a: loop { return; }
+ |
```
Questions for reviewer:
* The "desired output" in the linked issue had the main diagnostic be "misplaced loop label". Should the main diagnostic message the changed instead of leaving it as "block label not supported here"?
* Should this be `Applicability::MachineApplicable`?
Diffstat (limited to 'compiler/rustc_parse/src/parser/diagnostics.rs')
| -rw-r--r-- | compiler/rustc_parse/src/parser/diagnostics.rs | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 716ababb008..c1cca1186af 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2874,7 +2874,12 @@ impl<'a> Parser<'a> { first_pat } - pub(crate) fn maybe_recover_unexpected_block_label(&mut self) -> bool { + /// If `loop_header` is `Some` and an unexpected block label is encountered, + /// it is suggested to be moved just before `loop_header`, else it is suggested to be removed. + pub(crate) fn maybe_recover_unexpected_block_label( + &mut self, + loop_header: Option<Span>, + ) -> bool { // Check for `'a : {` if !(self.check_lifetime() && self.look_ahead(1, |t| *t == token::Colon) @@ -2885,16 +2890,28 @@ impl<'a> Parser<'a> { let label = self.eat_label().expect("just checked if a label exists"); self.bump(); // eat `:` let span = label.ident.span.to(self.prev_token.span); - self.dcx() + let mut diag = self + .dcx() .struct_span_err(span, "block label not supported here") - .with_span_label(span, "not supported here") - .with_tool_only_span_suggestion( + .with_span_label(span, "not supported here"); + if let Some(loop_header) = loop_header { + diag.multipart_suggestion( + "if you meant to label the loop, move this label before the loop", + vec![ + (label.ident.span.until(self.token.span), String::from("")), + (loop_header.shrink_to_lo(), format!("{}: ", label.ident)), + ], + Applicability::MachineApplicable, + ); + } else { + diag.tool_only_span_suggestion( label.ident.span.until(self.token.span), "remove this block label", "", Applicability::MachineApplicable, - ) - .emit(); + ); + } + diag.emit(); true } |
