Don't drop blocks on foreign functions

A code like

```rust
extern "C" {
    fn f() {
        fn g() {}
    }
}
```

is incorrect and does not compile. Today rustfmt formats this in a way
that is correct:

```rust
extern "C" {
    fn f();
}
```

But this loses information, and doesn't have to be done because we know
the content of the block if it is present. During development I don't
think rustfmt should drop the block in this context.

Closes #4313
This commit is contained in:
Ayaz Hafiz 2020-07-09 19:56:46 -07:00 committed by Caleb Cartwright
parent 5ffccbb627
commit 3bf67c175d
3 changed files with 23 additions and 2 deletions

View File

@ -3043,7 +3043,23 @@ impl Rewrite for ast::ForeignItem {
let span = mk_sp(self.span.lo(), self.span.hi() - BytePos(1));
let item_str = match self.kind {
ast::ForeignItemKind::Fn(_, ref fn_sig, ref generics, _) => rewrite_fn_base(
ast::ForeignItemKind::Fn(defaultness, ref fn_sig, ref generics, Some(ref body)) => {
let mut visitor = FmtVisitor::from_context(context);
visitor.block_indent = shape.indent;
visitor.last_pos = self.span.lo();
let inner_attrs = inner_attributes(&self.attrs);
let fn_ctxt = visit::FnCtxt::Foreign;
visitor.visit_fn(
visit::FnKind::Fn(fn_ctxt, self.ident, &fn_sig, &self.vis, Some(body)),
generics,
&fn_sig.decl,
self.span,
defaultness,
Some(&inner_attrs),
);
Some(visitor.buffer.to_owned())
}
ast::ForeignItemKind::Fn(_, ref fn_sig, ref generics, None) => rewrite_fn_base(
context,
shape.indent,
self.ident,

View File

@ -370,7 +370,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
// Note that this only gets called for function definitions. Required methods
// on traits do not get handled here.
fn visit_fn(
pub(crate) fn visit_fn(
&mut self,
fk: visit::FnKind<'_>,
generics: &ast::Generics,

View File

@ -0,0 +1,5 @@
extern "C" {
fn f() {
fn g() {}
}
}