Improve conflict marker recovery

This commit is contained in:
ardi 2024-06-07 16:25:43 +02:00
parent dd104ef163
commit d51b4462ec
15 changed files with 192 additions and 98 deletions

View file

@ -2990,14 +2990,18 @@ impl<'a> Parser<'a> {
}
pub(crate) fn err_vcs_conflict_marker(&mut self) -> PResult<'a, ()> {
// <<<<<<<
let Some(start) = self.conflict_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt)
else {
return Ok(());
};
let mut spans = Vec::with_capacity(3);
spans.push(start);
// |||||||
let mut middlediff3 = None;
// =======
let mut middle = None;
// >>>>>>>
let mut end = None;
loop {
if self.token.kind == TokenKind::Eof {
@ -3018,29 +3022,50 @@ impl<'a> Parser<'a> {
}
self.bump();
}
let mut err = self.dcx().struct_span_err(spans, "encountered diff marker");
err.span_label(start, "after this is the code before the merge");
if let Some(middle) = middlediff3 {
err.span_label(middle, "");
}
match middlediff3 {
// We're using diff3
Some(middlediff3) => {
err.span_label(
start,
"between this marker and `|||||||` is the code that we're merging into",
);
err.span_label(middlediff3, "between this marker and `=======` is the base code (what the two refs diverged from)");
}
None => {
err.span_label(
start,
"between this marker and `=======` is the code that we're merging into",
);
}
};
if let Some(middle) = middle {
err.span_label(middle, "");
err.span_label(middle, "between this marker and `>>>>>>>` is the incoming code");
}
if let Some(end) = end {
err.span_label(end, "above this are the incoming code changes");
err.span_label(end, "this marker concludes the conflict region");
}
err.help(
"if you're having merge conflicts after pulling new code, the top section is the code \
you already had and the bottom section is the remote code",
);
err.help(
"if you're in the middle of a rebase, the top section is the code being rebased onto \
and the bottom section is the code coming from the current commit being rebased",
);
err.note(
"for an explanation on these markers from the `git` documentation, visit \
<https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts>",
"conflict markers indicate that a merge was started but could not be completed due \
to merge conflicts\n\
to resolve a conflict, keep only the code you want and then delete the lines \
containing conflict markers",
);
err.help(
"if you're having merge conflicts after pulling new code:\n\
the top section is the code you already had and the bottom section is the remote code\n\
if you're in the middle of a rebase:\n\
the top section is the code being rebased onto and the bottom section is the code \
coming from the current commit being rebased",
);
err.note(
"for an explanation on these markers from the `git` documentation:\n\
visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts>",
);
Err(err)
}