Suggest using block for extern "abi" fn
with no body
This commit is contained in:
parent
18ca2946e0
commit
02fb345964
3 changed files with 92 additions and 11 deletions
|
@ -13,7 +13,9 @@ use rustc_ast::walk_list;
|
||||||
use rustc_ast::*;
|
use rustc_ast::*;
|
||||||
use rustc_ast_pretty::pprust::{self, State};
|
use rustc_ast_pretty::pprust::{self, State};
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
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_parse::validate_attr;
|
||||||
use rustc_session::lint::builtin::{
|
use rustc_session::lint::builtin::{
|
||||||
DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, PATTERNS_IN_FNS_WITHOUT_BODY,
|
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) {
|
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 source_map = self.session.source_map();
|
||||||
let end = source_map.end_point(sp);
|
let end = source_map.end_point(sp);
|
||||||
let replace_span = if source_map.span_to_snippet(end).map(|s| s == ";").unwrap_or(false) {
|
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 {
|
} else {
|
||||||
sp.shrink_to_hi()
|
sp.shrink_to_hi()
|
||||||
};
|
};
|
||||||
self.err_handler()
|
let mut err = self.err_handler().struct_span_err(sp, msg);
|
||||||
.struct_span_err(sp, msg)
|
err.span_suggestion(
|
||||||
.span_suggestion(
|
|
||||||
replace_span,
|
replace_span,
|
||||||
&format!("provide a definition for the {}", ctx),
|
&format!("provide a definition for the {}", ctx),
|
||||||
sugg,
|
sugg,
|
||||||
Applicability::HasPlaceholders,
|
Applicability::HasPlaceholders,
|
||||||
)
|
);
|
||||||
.emit();
|
help(&mut err);
|
||||||
|
err.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_impl_item_provided<T>(&self, sp: Span, body: &Option<T>, ctx: &str, sugg: &str) {
|
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() {
|
if body.is_none() {
|
||||||
let msg = "free function without a body";
|
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_vis(&item.vis);
|
||||||
self.visit_ident(item.ident);
|
self.visit_ident(item.ident);
|
||||||
let kind =
|
let kind =
|
||||||
|
|
6
src/test/ui/extern/not-in-block.rs
vendored
Normal file
6
src/test/ui/extern/not-in-block.rs
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
|
extern fn none_fn(x: bool) -> i32;
|
||||||
|
//~^ ERROR free function without a body
|
||||||
|
extern "C" fn c_fn(x: bool) -> i32;
|
||||||
|
//~^ ERROR free function without a body
|
32
src/test/ui/extern/not-in-block.stderr
vendored
Normal file
32
src/test/ui/extern/not-in-block.stderr
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
error: free function without a body
|
||||||
|
--> $DIR/not-in-block.rs:3:1
|
||||||
|
|
|
||||||
|
LL | extern fn none_fn(x: bool) -> i32;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: provide a definition for the function
|
||||||
|
|
|
||||||
|
LL | extern fn none_fn(x: bool) -> i32 { <body> }
|
||||||
|
| ~~~~~~~~~~
|
||||||
|
help: if you meant to declare an externally defined function, use an `extern` block
|
||||||
|
|
|
||||||
|
LL | extern { fn none_fn(x: bool) -> i32; }
|
||||||
|
| ~~~~~~~~ +
|
||||||
|
|
||||||
|
error: free function without a body
|
||||||
|
--> $DIR/not-in-block.rs:5:1
|
||||||
|
|
|
||||||
|
LL | extern "C" fn c_fn(x: bool) -> i32;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: provide a definition for the function
|
||||||
|
|
|
||||||
|
LL | extern "C" fn c_fn(x: bool) -> i32 { <body> }
|
||||||
|
| ~~~~~~~~~~
|
||||||
|
help: if you meant to declare an externally defined function, use an `extern` block
|
||||||
|
|
|
||||||
|
LL | extern "C" { fn c_fn(x: bool) -> i32; }
|
||||||
|
| ~~~~~~~~~~~~ +
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue