From eadc878de01b99347c8f6e627459e5d69a307b8b Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Mon, 11 Apr 2016 21:20:03 +1200 Subject: [PATCH] Handle variadic function types Closes #842 --- src/expr.rs | 2 +- src/types.rs | 48 ++++++++++++++++++++++++++++++++++++++++---- tests/source/type.rs | 8 ++++++++ tests/target/type.rs | 14 +++++++++++++ 4 files changed, 67 insertions(+), 5 deletions(-) diff --git a/src/expr.rs b/src/expr.rs index 7ee69885a42..0c30aaf3f6f 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -981,7 +981,7 @@ fn rewrite(&self, context: &RewriteContext, width: usize, offset: Indent) -> Opt .collect::>>()); let all_simple = pat_strs.iter().all(|p| pat_is_simple(&p)); - let items: Vec<_> = pat_strs.into_iter().map(|s| ListItem::from_str(s)).collect(); + let items: Vec<_> = pat_strs.into_iter().map(ListItem::from_str).collect(); let fmt = ListFormatting { tactic: if all_simple { DefinitiveListTactic::Mixed diff --git a/src/types.rs b/src/types.rs index 51bebc409e0..09cf7e12126 100644 --- a/src/types.rs +++ b/src/types.rs @@ -220,6 +220,7 @@ fn rewrite_segment(expr_context: bool, }; try_opt!(format_function_type(data.inputs.iter().map(|x| &**x), &output, + false, data.span, context, width, @@ -233,6 +234,7 @@ fn rewrite_segment(expr_context: bool, fn format_function_type<'a, I>(inputs: I, output: &FunctionRetTy, + variadic: bool, span: Span, context: &RewriteContext, width: usize, @@ -242,17 +244,54 @@ fn format_function_type<'a, I>(inputs: I, ::Item: Deref, ::Target: Rewrite + Spanned + 'a { + // Code for handling variadics is somewhat duplicated for items, but they + // are different enough to need some serious refactoring to share code. + enum ArgumentKind + where T: Deref, + ::Target: Rewrite + Spanned + { + Regular(Box), + Variadic(BytePos), + } + + let variadic_arg = if variadic { + let variadic_start = context.codemap.span_before(span, "..."); + Some(ArgumentKind::Variadic(variadic_start)) + } else { + None + }; + // 2 for () let budget = try_opt!(width.checked_sub(2)); // 1 for ( let offset = offset + 1; let list_lo = context.codemap.span_after(span, "("); let items = itemize_list(context.codemap, - inputs, + // FIXME Would be nice to avoid this allocation, + // but I couldn't get the types to work out. + inputs.map(|i| ArgumentKind::Regular(Box::new(i))) + .chain(variadic_arg), ")", - |ty| ty.span().lo, - |ty| ty.span().hi, - |ty| ty.rewrite(context, budget, offset), + |arg| { + match *arg { + ArgumentKind::Regular(ref ty) => ty.span().lo, + ArgumentKind::Variadic(start) => start, + } + }, + |arg| { + match *arg { + ArgumentKind::Regular(ref ty) => ty.span().hi, + ArgumentKind::Variadic(start) => start + BytePos(3), + } + }, + |arg| { + match *arg { + ArgumentKind::Regular(ref ty) => { + ty.rewrite(context, budget, offset) + } + ArgumentKind::Variadic(_) => Some("...".to_owned()), + } + }, list_lo, span.hi); @@ -579,6 +618,7 @@ fn rewrite_bare_fn(bare_fn: &ast::BareFnTy, let rewrite = try_opt!(format_function_type(bare_fn.decl.inputs.iter(), &bare_fn.decl.output, + bare_fn.decl.variadic, span, context, budget, diff --git a/tests/source/type.rs b/tests/source/type.rs index 71822bd668d..dcb8e0d0f31 100644 --- a/tests/source/type.rs +++ b/tests/source/type.rs @@ -4,3 +4,11 @@ fn types() { let z: (/*#digits*/ usize, /*exp*/ i16) = funk(); let z: ( usize /*#digits*/ , i16 /*exp*/ ) = funk(); } + +struct F { + f: extern "C" fn(x: u8, ... /* comment */), + g: extern "C" fn(x: u8,/* comment */ ...), + h: extern "C" fn(x: u8, ... ), + i: extern "C" fn(x: u8, /* comment 4*/ y: String, // comment 3 + z: Foo, /* comment */ .../* comment 2*/ ), +} diff --git a/tests/target/type.rs b/tests/target/type.rs index a8a5e028aa5..1ae1143bcca 100644 --- a/tests/target/type.rs +++ b/tests/target/type.rs @@ -7,3 +7,17 @@ fn types() { i16) = funk(); let z: (usize /* #digits */, i16 /* exp */) = funk(); } + +struct F { + f: extern "C" fn(x: u8, ... /* comment */), + g: extern "C" fn(x: u8, + // comment + ...), + h: extern "C" fn(x: u8, ...), + i: extern "C" fn(x: u8, + // comment 4 + y: String, // comment 3 + z: Foo, + // comment + ... /* comment 2 */), +} -- 2.44.0