Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add suggestion for PATTERNS_IN_FNS_WITHOUT_BODY #79414

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 17 additions & 8 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Expand Up @@ -16,7 +16,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{error_code, pluralize, struct_span_err, Applicability};
use rustc_parse::validate_attr;
use rustc_session::lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY;
use rustc_session::lint::LintBuffer;
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
use rustc_session::Session;
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Span;
Expand Down Expand Up @@ -213,14 +213,14 @@ impl<'a> AstValidator<'a> {
err.emit();
}

fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, bool)) {
fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, Option<Ident>, bool)) {
for Param { pat, .. } in &decl.inputs {
match pat.kind {
PatKind::Ident(BindingMode::ByValue(Mutability::Not), _, None) | PatKind::Wild => {}
PatKind::Ident(BindingMode::ByValue(Mutability::Mut), _, None) => {
report_err(pat.span, true)
PatKind::Ident(BindingMode::ByValue(Mutability::Mut), ident, None) => {
report_err(pat.span, Some(ident), true)
}
_ => report_err(pat.span, false),
_ => report_err(pat.span, None, false),
}
}
}
Expand Down Expand Up @@ -815,7 +815,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
match ty.kind {
TyKind::BareFn(ref bfty) => {
self.check_fn_decl(&bfty.decl, SelfSemantic::No);
Self::check_decl_no_pat(&bfty.decl, |span, _| {
Self::check_decl_no_pat(&bfty.decl, |span, _, _| {
struct_span_err!(
self.session,
span,
Expand Down Expand Up @@ -1285,7 +1285,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {

// Functions without bodies cannot have patterns.
if let FnKind::Fn(ctxt, _, sig, _, None) = fk {
Self::check_decl_no_pat(&sig.decl, |span, mut_ident| {
Self::check_decl_no_pat(&sig.decl, |span, ident, mut_ident| {
let (code, msg, label) = match ctxt {
FnCtxt::Foreign => (
error_code!(E0130),
Expand All @@ -1299,7 +1299,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
),
};
if mut_ident && matches!(ctxt, FnCtxt::Assoc(_)) {
self.lint_buffer.buffer_lint(PATTERNS_IN_FNS_WITHOUT_BODY, id, span, msg);
if let Some(ident) = ident {
let diag = BuiltinLintDiagnostics::PatternsInFnsWithoutBody(span, ident);
self.lint_buffer.buffer_lint_with_diagnostic(
PATTERNS_IN_FNS_WITHOUT_BODY,
id,
span,
msg,
diag,
)
}
} else {
self.err_handler()
.struct_span_err(span, msg)
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_lint/src/context.rs
Expand Up @@ -596,6 +596,9 @@ pub trait LintContext: Sized {
db.help("to document an item produced by a macro, \
the macro must produce the documentation as part of its expansion");
}
BuiltinLintDiagnostics::PatternsInFnsWithoutBody(span, ident) => {
db.span_suggestion(span, "remove `mut` from the parameter", ident.to_string(), Applicability::MachineApplicable);
}
}
// Rewrap `db`, and pass control to the user.
decorate(LintDiagnosticBuilder::new(db));
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_lint_defs/src/lib.rs
Expand Up @@ -253,6 +253,7 @@ pub enum BuiltinLintDiagnostics {
RedundantImport(Vec<(Span, bool)>, Ident),
DeprecatedMacro(Option<Symbol>, Span),
UnusedDocComment(Span),
PatternsInFnsWithoutBody(Span, Ident),
}

/// Lints that are buffered up early on in the `Session` before the
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/no-patterns-in-args-2.stderr
Expand Up @@ -8,7 +8,7 @@ error: patterns aren't allowed in functions without bodies
--> $DIR/no-patterns-in-args-2.rs:4:11
|
LL | fn f1(mut arg: u8);
| ^^^^^^^
| ^^^^^^^ help: remove `mut` from the parameter: `arg`
|
note: the lint level is defined here
--> $DIR/no-patterns-in-args-2.rs:1:9
Expand Down