Skip to content

Commit 6554e7c

Browse files
authored
Merge pull request #1916 from topecongiro/issue-1914
Implement Rewrite trait for ast::ForeignItem
2 parents 1a02c35 + 34cf164 commit 6554e7c

File tree

5 files changed

+90
-58
lines changed

5 files changed

+90
-58
lines changed

src/items.rs

Lines changed: 69 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -185,64 +185,11 @@ impl<'a> FmtVisitor<'a> {
185185
self.format_item(item);
186186
}
187187

188-
fn format_foreign_item(&mut self, item: &ast::ForeignItem) {
189-
self.format_missing_with_indent(item.span.lo);
190-
// Drop semicolon or it will be interpreted as comment.
191-
// FIXME: this may be a faulty span from libsyntax.
192-
let span = mk_sp(item.span.lo, item.span.hi - BytePos(1));
193-
194-
match item.node {
195-
ast::ForeignItemKind::Fn(ref fn_decl, ref generics) => {
196-
let indent = self.block_indent;
197-
let rewrite = rewrite_fn_base(
198-
&self.get_context(),
199-
indent,
200-
item.ident,
201-
fn_decl,
202-
generics,
203-
ast::Unsafety::Normal,
204-
ast::Constness::NotConst,
205-
ast::Defaultness::Final,
206-
// These are not actually rust functions,
207-
// but we format them as such.
208-
abi::Abi::Rust,
209-
&item.vis,
210-
span,
211-
false,
212-
false,
213-
false,
214-
);
215-
216-
match rewrite {
217-
Some((new_fn, _)) => {
218-
self.buffer.push_str(&new_fn);
219-
self.buffer.push_str(";");
220-
}
221-
None => self.format_missing(item.span.hi),
222-
}
223-
}
224-
ast::ForeignItemKind::Static(ref ty, is_mutable) => {
225-
// FIXME(#21): we're dropping potential comments in between the
226-
// function keywords here.
227-
let vis = format_visibility(&item.vis);
228-
let mut_str = if is_mutable { "mut " } else { "" };
229-
let prefix = format!("{}static {}{}: ", vis, mut_str, item.ident);
230-
let offset = self.block_indent + prefix.len();
231-
// 1 = ;
232-
let shape = Shape::indented(offset, self.config).sub_width(1).unwrap();
233-
let rewrite = ty.rewrite(&self.get_context(), shape);
234-
235-
match rewrite {
236-
Some(result) => {
237-
self.buffer.push_str(&prefix);
238-
self.buffer.push_str(&result);
239-
self.buffer.push_str(";");
240-
}
241-
None => self.format_missing(item.span.hi),
242-
}
243-
}
244-
}
245188

189+
fn format_foreign_item(&mut self, item: &ast::ForeignItem) {
190+
let shape = Shape::indented(self.block_indent, self.config);
191+
let rewrite = item.rewrite(&self.get_context(), shape);
192+
self.push_rewrite(item.span(), rewrite);
246193
self.last_pos = item.span.hi;
247194
}
248195

@@ -2837,3 +2784,68 @@ fn format_generics(
28372784

28382785
Some(result)
28392786
}
2787+
2788+
impl Rewrite for ast::ForeignItem {
2789+
fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
2790+
let attrs_str = try_opt!(self.attrs.rewrite(context, shape));
2791+
// Drop semicolon or it will be interpreted as comment.
2792+
// FIXME: this may be a faulty span from libsyntax.
2793+
let span = mk_sp(self.span.lo, self.span.hi - BytePos(1));
2794+
2795+
let item_str = try_opt!(match self.node {
2796+
ast::ForeignItemKind::Fn(ref fn_decl, ref generics) => {
2797+
rewrite_fn_base(
2798+
context,
2799+
shape.indent,
2800+
self.ident,
2801+
fn_decl,
2802+
generics,
2803+
ast::Unsafety::Normal,
2804+
ast::Constness::NotConst,
2805+
ast::Defaultness::Final,
2806+
// These are not actually rust functions,
2807+
// but we format them as such.
2808+
abi::Abi::Rust,
2809+
&self.vis,
2810+
span,
2811+
false,
2812+
false,
2813+
false,
2814+
).map(|(s, _)| format!("{};", s))
2815+
}
2816+
ast::ForeignItemKind::Static(ref ty, is_mutable) => {
2817+
// FIXME(#21): we're dropping potential comments in between the
2818+
// function keywords here.
2819+
let vis = format_visibility(&self.vis);
2820+
let mut_str = if is_mutable { "mut " } else { "" };
2821+
let prefix = format!("{}static {}{}:", vis, mut_str, self.ident);
2822+
// 1 = ;
2823+
let shape = try_opt!(shape.sub_width(1));
2824+
ty.rewrite(context, shape).map(|ty_str| {
2825+
// 1 = space between prefix and type.
2826+
let sep = if prefix.len() + ty_str.len() + 1 <= shape.width {
2827+
String::from(" ")
2828+
} else {
2829+
let nested_indent = shape.indent.block_indent(context.config);
2830+
format!("\n{}", nested_indent.to_string(context.config))
2831+
};
2832+
format!("{}{}{};", prefix, sep, ty_str)
2833+
})
2834+
}
2835+
});
2836+
2837+
let missing_span = if self.attrs.is_empty() {
2838+
mk_sp(self.span.lo, self.span.lo)
2839+
} else {
2840+
mk_sp(self.attrs[self.attrs.len() - 1].span.hi, self.span.lo)
2841+
};
2842+
combine_strs_with_missing_comments(
2843+
context,
2844+
&attrs_str,
2845+
&item_str,
2846+
missing_span,
2847+
shape,
2848+
false,
2849+
)
2850+
}
2851+
}

src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ mod patterns;
7474
mod summary;
7575
mod vertical;
7676

77+
/// Spanned returns a span including attributes, if available.
7778
pub trait Spanned {
7879
fn span(&self) -> Span;
7980
}
@@ -207,6 +208,12 @@ impl Spanned for ast::TyParamBound {
207208
}
208209
}
209210

211+
impl Spanned for ast::ForeignItem {
212+
fn span(&self) -> Span {
213+
span_with_attrs!(self)
214+
}
215+
}
216+
210217
#[derive(Copy, Clone, Debug)]
211218
pub struct Indent {
212219
// Width of the block indent, in characters. Must be a multiple of

src/visitor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ impl<'a> FmtVisitor<'a> {
641641
self.push_rewrite(mac.span, rewrite);
642642
}
643643

644-
fn push_rewrite(&mut self, span: Span, rewrite: Option<String>) {
644+
pub fn push_rewrite(&mut self, span: Span, rewrite: Option<String>) {
645645
self.format_missing_with_indent(source!(self, span).lo);
646646
let result = rewrite.unwrap_or_else(|| self.snippet(span));
647647
self.buffer.push_str(&result);

tests/source/issue-1914.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// rustfmt-max_width: 80
2+
3+
extern "C" {
4+
#[link_name = "_ZN7MyClass26example_check_no_collisionE"]
5+
pub static mut MyClass_example_check_no_collision : * const :: std :: os :: raw :: c_int ;
6+
}

tests/target/issue-1914.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// rustfmt-max_width: 80
2+
3+
extern "C" {
4+
#[link_name = "_ZN7MyClass26example_check_no_collisionE"]
5+
pub static mut MyClass_example_check_no_collision:
6+
*const ::std::os::raw::c_int;
7+
}

0 commit comments

Comments
 (0)