Auto merge of #117297 - clubby789:fn-trait-missing-paren, r=TaKO8Ki

Give a better diagnostic for missing parens in Fn* bounds

Fixes #108109

It would be nice to try and recover here, but I'm not sure it's worth the effort, especially as the bounds on the recovered function would be incorrect.
This commit is contained in:
bors 2023-11-07 13:04:56 +00:00
commit 187d1afa9d
7 changed files with 73 additions and 0 deletions

View file

@ -1378,6 +1378,34 @@ pub(crate) struct FnPtrWithGenericsSugg {
pub for_param_list_exists: bool,
}
pub(crate) struct FnTraitMissingParen {
pub span: Span,
pub machine_applicable: bool,
}
impl AddToDiagnostic for FnTraitMissingParen {
fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
where
F: Fn(
&mut rustc_errors::Diagnostic,
rustc_errors::SubdiagnosticMessage,
) -> rustc_errors::SubdiagnosticMessage,
{
diag.span_label(self.span, crate::fluent_generated::parse_fn_trait_missing_paren);
let applicability = if self.machine_applicable {
Applicability::MachineApplicable
} else {
Applicability::MaybeIncorrect
};
diag.span_suggestion_short(
self.span.shrink_to_hi(),
crate::fluent_generated::parse_add_paren,
"()",
applicability,
);
}
}
#[derive(Diagnostic)]
#[diag(parse_unexpected_if_with_if)]
pub(crate) struct UnexpectedIfWithIf(

View file

@ -2278,6 +2278,18 @@ impl<'a> Parser<'a> {
err.span_label(ident.span, "while parsing this `fn`");
err.emit();
} else {
// check for typo'd Fn* trait bounds such as
// fn foo<F>() where F: FnOnce -> () {}
if self.token.kind == token::RArrow {
let machine_applicable = [sym::FnOnce, sym::FnMut, sym::Fn]
.into_iter()
.any(|s| self.prev_token.is_ident_named(s));
err.subdiagnostic(errors::FnTraitMissingParen {
span: self.prev_token.span,
machine_applicable,
});
}
return Err(err);
}
}