From 1f9e7c25c95b1cd267c0e54669021e0b56462d94 Mon Sep 17 00:00:00 2001 From: topecongiro <seuchida@gmail.com> Date: Fri, 25 Aug 2017 08:19:51 +0900 Subject: [PATCH 1/2] Implement Rewrite trait for ast::ForeignItem --- src/items.rs | 126 +++++++++++++++++++++++++++---------------------- src/lib.rs | 7 +++ src/visitor.rs | 2 +- 3 files changed, 77 insertions(+), 58 deletions(-) diff --git a/src/items.rs b/src/items.rs index c42ef7f971c..9dd1972670a 100644 --- a/src/items.rs +++ b/src/items.rs @@ -185,64 +185,11 @@ impl<'a> FmtVisitor<'a> { self.format_item(item); } + fn format_foreign_item(&mut self, item: &ast::ForeignItem) { - self.format_missing_with_indent(item.span.lo); - // Drop semicolon or it will be interpreted as comment. - // FIXME: this may be a faulty span from libsyntax. - let span = mk_sp(item.span.lo, item.span.hi - BytePos(1)); - - match item.node { - ast::ForeignItemKind::Fn(ref fn_decl, ref generics) => { - let indent = self.block_indent; - let rewrite = rewrite_fn_base( - &self.get_context(), - indent, - item.ident, - fn_decl, - generics, - ast::Unsafety::Normal, - ast::Constness::NotConst, - ast::Defaultness::Final, - // These are not actually rust functions, - // but we format them as such. - abi::Abi::Rust, - &item.vis, - span, - false, - false, - false, - ); - - match rewrite { - Some((new_fn, _)) => { - self.buffer.push_str(&new_fn); - self.buffer.push_str(";"); - } - None => self.format_missing(item.span.hi), - } - } - ast::ForeignItemKind::Static(ref ty, is_mutable) => { - // FIXME(#21): we're dropping potential comments in between the - // function keywords here. - let vis = format_visibility(&item.vis); - let mut_str = if is_mutable { "mut " } else { "" }; - let prefix = format!("{}static {}{}: ", vis, mut_str, item.ident); - let offset = self.block_indent + prefix.len(); - // 1 = ; - let shape = Shape::indented(offset, self.config).sub_width(1).unwrap(); - let rewrite = ty.rewrite(&self.get_context(), shape); - - match rewrite { - Some(result) => { - self.buffer.push_str(&prefix); - self.buffer.push_str(&result); - self.buffer.push_str(";"); - } - None => self.format_missing(item.span.hi), - } - } - } - + let shape = Shape::indented(self.block_indent, self.config); + let rewrite = item.rewrite(&self.get_context(), shape); + self.push_rewrite(item.span(), rewrite); self.last_pos = item.span.hi; } @@ -2837,3 +2784,68 @@ fn format_generics( Some(result) } + +impl Rewrite for ast::ForeignItem { + fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> { + let attrs_str = try_opt!(self.attrs.rewrite(context, shape)); + // Drop semicolon or it will be interpreted as comment. + // FIXME: this may be a faulty span from libsyntax. + let span = mk_sp(self.span.lo, self.span.hi - BytePos(1)); + + let item_str = try_opt!(match self.node { + ast::ForeignItemKind::Fn(ref fn_decl, ref generics) => { + rewrite_fn_base( + context, + shape.indent, + self.ident, + fn_decl, + generics, + ast::Unsafety::Normal, + ast::Constness::NotConst, + ast::Defaultness::Final, + // These are not actually rust functions, + // but we format them as such. + abi::Abi::Rust, + &self.vis, + span, + false, + false, + false, + ).map(|(s, _)| format!("{};", s)) + } + ast::ForeignItemKind::Static(ref ty, is_mutable) => { + // FIXME(#21): we're dropping potential comments in between the + // function keywords here. + let vis = format_visibility(&self.vis); + let mut_str = if is_mutable { "mut " } else { "" }; + let prefix = format!("{}static {}{}:", vis, mut_str, self.ident); + // 1 = ; + let shape = try_opt!(shape.sub_width(1)); + ty.rewrite(context, shape).map(|ty_str| { + // 1 = space between prefix and type. + let sep = if prefix.len() + ty_str.len() + 1 <= shape.width { + String::from(" ") + } else { + let nested_indent = shape.indent.block_indent(context.config); + format!("\n{}", nested_indent.to_string(context.config)) + }; + format!("{}{}{};", prefix, sep, ty_str) + }) + } + }); + + let missing_span = if self.attrs.is_empty() { + mk_sp(self.span.lo, self.span.lo) + } else { + mk_sp(self.attrs[self.attrs.len() - 1].span.hi, self.span.lo) + }; + combine_strs_with_missing_comments( + context, + &attrs_str, + &item_str, + missing_span, + shape, + false, + ) + } +} diff --git a/src/lib.rs b/src/lib.rs index 1b19689b660..432e61e874b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -74,6 +74,7 @@ mod patterns; mod summary; mod vertical; +/// Spanned returns a span including attributes, if available. pub trait Spanned { fn span(&self) -> Span; } @@ -207,6 +208,12 @@ impl Spanned for ast::TyParamBound { } } +impl Spanned for ast::ForeignItem { + fn span(&self) -> Span { + span_with_attrs!(self) + } +} + #[derive(Copy, Clone, Debug)] pub struct Indent { // Width of the block indent, in characters. Must be a multiple of diff --git a/src/visitor.rs b/src/visitor.rs index 2f6a503dc13..bf1afb0c3f0 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -641,7 +641,7 @@ impl<'a> FmtVisitor<'a> { self.push_rewrite(mac.span, rewrite); } - fn push_rewrite(&mut self, span: Span, rewrite: Option<String>) { + pub fn push_rewrite(&mut self, span: Span, rewrite: Option<String>) { self.format_missing_with_indent(source!(self, span).lo); let result = rewrite.unwrap_or_else(|| self.snippet(span)); self.buffer.push_str(&result); From 34cf16436ac8cd25a490f678848af2e620dea84f Mon Sep 17 00:00:00 2001 From: topecongiro <seuchida@gmail.com> Date: Fri, 25 Aug 2017 08:20:11 +0900 Subject: [PATCH 2/2] Add a test for #1914 and #1915 --- tests/source/issue-1914.rs | 6 ++++++ tests/target/issue-1914.rs | 7 +++++++ 2 files changed, 13 insertions(+) create mode 100644 tests/source/issue-1914.rs create mode 100644 tests/target/issue-1914.rs diff --git a/tests/source/issue-1914.rs b/tests/source/issue-1914.rs new file mode 100644 index 00000000000..447296c4b87 --- /dev/null +++ b/tests/source/issue-1914.rs @@ -0,0 +1,6 @@ +// rustfmt-max_width: 80 + +extern "C" { +#[link_name = "_ZN7MyClass26example_check_no_collisionE"] + pub static mut MyClass_example_check_no_collision : * const :: std :: os :: raw :: c_int ; +} diff --git a/tests/target/issue-1914.rs b/tests/target/issue-1914.rs new file mode 100644 index 00000000000..d2d532af1dc --- /dev/null +++ b/tests/target/issue-1914.rs @@ -0,0 +1,7 @@ +// rustfmt-max_width: 80 + +extern "C" { + #[link_name = "_ZN7MyClass26example_check_no_collisionE"] + pub static mut MyClass_example_check_no_collision: + *const ::std::os::raw::c_int; +}