1
Fork 0

Suggest using block for extern "abi" fn with no body

This commit is contained in:
Nixon Enraght-Moony 2022-07-02 18:53:16 +01:00
parent 18ca2946e0
commit 02fb345964
3 changed files with 92 additions and 11 deletions

View file

@ -13,7 +13,9 @@ use rustc_ast::walk_list;
use rustc_ast::*;
use rustc_ast_pretty::pprust::{self, State};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{error_code, pluralize, struct_span_err, Applicability};
use rustc_errors::{
error_code, pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed,
};
use rustc_parse::validate_attr;
use rustc_session::lint::builtin::{
DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, PATTERNS_IN_FNS_WITHOUT_BODY,
@ -476,6 +478,17 @@ impl<'a> AstValidator<'a> {
}
fn error_item_without_body(&self, sp: Span, ctx: &str, msg: &str, sugg: &str) {
self.error_item_without_body_with_help(sp, ctx, msg, sugg, |_| ());
}
fn error_item_without_body_with_help(
&self,
sp: Span,
ctx: &str,
msg: &str,
sugg: &str,
help: impl FnOnce(&mut DiagnosticBuilder<'_, ErrorGuaranteed>),
) {
let source_map = self.session.source_map();
let end = source_map.end_point(sp);
let replace_span = if source_map.span_to_snippet(end).map(|s| s == ";").unwrap_or(false) {
@ -483,15 +496,15 @@ impl<'a> AstValidator<'a> {
} else {
sp.shrink_to_hi()
};
self.err_handler()
.struct_span_err(sp, msg)
.span_suggestion(
replace_span,
&format!("provide a definition for the {}", ctx),
sugg,
Applicability::HasPlaceholders,
)
.emit();
let mut err = self.err_handler().struct_span_err(sp, msg);
err.span_suggestion(
replace_span,
&format!("provide a definition for the {}", ctx),
sugg,
Applicability::HasPlaceholders,
);
help(&mut err);
err.emit();
}
fn check_impl_item_provided<T>(&self, sp: Span, body: &Option<T>, ctx: &str, sugg: &str) {
@ -1191,8 +1204,38 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
if body.is_none() {
let msg = "free function without a body";
self.error_item_without_body(item.span, "function", msg, " { <body> }");
let ext = sig.header.ext;
let f = |e: &mut DiagnosticBuilder<'_, _>| {
if let Extern::Implicit(start_span) | Extern::Explicit(_, start_span) = &ext
{
let start_suggestion = if let Extern::Explicit(abi, _) = ext {
format!("extern \"{}\" {{", abi.symbol_unescaped)
} else {
"extern {".to_owned()
};
let end_suggestion = " }".to_owned();
let end_span = item.span.shrink_to_hi();
e
.multipart_suggestion(
"if you meant to declare an externally defined function, use an `extern` block",
vec![(*start_span, start_suggestion), (end_span, end_suggestion)],
Applicability::MaybeIncorrect,
);
}
};
self.error_item_without_body_with_help(
item.span,
"function",
msg,
" { <body> }",
f,
);
}
self.visit_vis(&item.vis);
self.visit_ident(item.ident);
let kind =