diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2019-07-13 21:15:21 -0700 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2019-07-13 22:24:11 -0700 |
| commit | c8d9cd99fa2f389a69c0c42de9945f46977b11d7 (patch) | |
| tree | a70feac92e2938627d6300829c670c9b38b8c22c /src/libsyntax/parse/diagnostics.rs | |
| parent | 69656fa4cbafc378fd63f9186d93b0df3cdd9320 (diff) | |
| download | rust-c8d9cd99fa2f389a69c0c42de9945f46977b11d7.tar.gz rust-c8d9cd99fa2f389a69c0c42de9945f46977b11d7.zip | |
Detect `fn` with a body in an `extern` block
Diffstat (limited to 'src/libsyntax/parse/diagnostics.rs')
| -rw-r--r-- | src/libsyntax/parse/diagnostics.rs | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs index ae24047ac82..de392d6bb81 100644 --- a/src/libsyntax/parse/diagnostics.rs +++ b/src/libsyntax/parse/diagnostics.rs @@ -15,6 +15,7 @@ use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; use rustc_data_structures::fx::FxHashSet; use syntax_pos::{Span, DUMMY_SP, MultiSpan}; use log::{debug, trace}; +use std::mem; /// Creates a placeholder argument. crate fn dummy_arg(ident: Ident) -> Arg { @@ -783,6 +784,42 @@ impl<'a> Parser<'a> { Err(err) } + crate fn parse_semi_or_incorrect_foreign_fn_body( + &mut self, + ident: &Ident, + extern_sp: Span, + ) -> PResult<'a, ()> { + if self.token != token::Semi { + // this might be an incorrect fn definition (#62109) + let parser_snapshot = self.clone(); + match self.parse_inner_attrs_and_block() { + Ok((_, body)) => { + self.struct_span_err(ident.span, "incorrect `fn` inside `extern` block") + .span_label(ident.span, "can't have a body") + .span_label(body.span, "this body is invalid here") + .span_label( + extern_sp, + "`extern` blocks define existing foreign functions and `fn`s \ + inside of them can't have a body") + .help("you might have meant to write a function accessible through ffi, \ + which can be done by writing `extern fn` outside of the \ + `extern` block") + .note("for more information, visit \ + https://doc.rust-lang.org/std/keyword.extern.html") + .emit(); + } + Err(mut err) => { + err.cancel(); + mem::replace(self, parser_snapshot); + self.expect(&token::Semi)?; + } + } + } else { + self.bump(); + } + Ok(()) + } + /// Consume alternative await syntaxes like `await <expr>`, `await? <expr>`, `await(<expr>)` /// and `await { <expr> }`. crate fn parse_incorrect_await_syntax( |
