about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authortopecongiro <seuchida@gmail.com>2018-02-07 22:48:05 +0900
committertopecongiro <seuchida@gmail.com>2018-02-07 22:48:05 +0900
commit4af2aa3a9e2ab32e584c3d7bc97d74bdc8b35836 (patch)
treeab74c699216d5b6bcafb21dcf6b09a2878efa05d /src
parentc9e250a1ab4983875cba2dcd5f083a6694d70e8f (diff)
Create rustfmt_core crate
Diffstat (limited to 'src')
-rw-r--r--src/chains.rs499
-rw-r--r--src/checkstyle.rs85
-rw-r--r--src/closures.rs392
-rw-r--r--src/codemap.rs100
-rw-r--r--src/comment.rs1234
-rw-r--r--src/expr.rs2930
-rw-r--r--src/filemap.rs179
-rw-r--r--src/imports.rs600
-rw-r--r--src/issues.rs325
-rw-r--r--src/items.rs2845
-rw-r--r--src/lib.rs828
-rw-r--r--src/lists.rs857
-rw-r--r--src/macros.rs871
-rw-r--r--src/missed_spans.rs312
-rw-r--r--src/modules.rs86
-rw-r--r--src/patterns.rs379
-rw-r--r--src/rewrite.rs54
-rw-r--r--src/rustfmt_diff.rs247
-rw-r--r--src/shape.rs353
-rw-r--r--src/spanned.rs187
-rw-r--r--src/string.rs163
-rw-r--r--src/types.rs820
-rw-r--r--src/utils.rs480
-rw-r--r--src/vertical.rs290
-rw-r--r--src/visitor.rs1113
25 files changed, 0 insertions, 16229 deletions
diff --git a/src/chains.rs b/src/chains.rs
deleted file mode 100644
index 383e7077d66..00000000000
--- a/src/chains.rs
+++ /dev/null
@@ -1,499 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Formatting of chained expressions, i.e. expressions which are chained by
-//! dots: struct and enum field access, method calls, and try shorthand (?).
-//!
-//! Instead of walking these subexpressions one-by-one, as is our usual strategy
-//! for expression formatting, we collect maximal sequences of these expressions
-//! and handle them simultaneously.
-//!
-//! Whenever possible, the entire chain is put on a single line. If that fails,
-//! we put each subexpression on a separate, much like the (default) function
-//! argument function argument strategy.
-//!
-//! Depends on config options: `chain_indent` is the indent to use for
-//! blocks in the parent/root/base of the chain (and the rest of the chain's
-//! alignment).
-//! E.g., `let foo = { aaaa; bbb; ccc }.bar.baz();`, we would layout for the
-//! following values of `chain_indent`:
-//! Block:
-//! ```
-//! let foo = {
-//!     aaaa;
-//!     bbb;
-//!     ccc
-//! }.bar
-//!     .baz();
-//! ```
-//! Visual:
-//! ```
-//! let foo = {
-//!               aaaa;
-//!               bbb;
-//!               ccc
-//!           }
-//!           .bar
-//!           .baz();
-//! ```
-//!
-//! If the first item in the chain is a block expression, we align the dots with
-//! the braces.
-//! Block:
-//! ```
-//! let a = foo.bar
-//!     .baz()
-//!     .qux
-//! ```
-//! Visual:
-//! ```
-//! let a = foo.bar
-//!            .baz()
-//!            .qux
-//! ```
-
-use config::IndentStyle;
-use expr::rewrite_call;
-use macros::convert_try_mac;
-use rewrite::{Rewrite, RewriteContext};
-use shape::Shape;
-use utils::{first_line_width, last_line_extendable, last_line_width, mk_sp,
-            trimmed_last_line_width, wrap_str};
-
-use std::cmp::min;
-use std::iter;
-use syntax::{ast, ptr};
-use syntax::codemap::Span;
-
-pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) -> Option<String> {
-    debug!("rewrite_chain {:?}", shape);
-    let total_span = expr.span;
-    let (parent, subexpr_list) = make_subexpr_list(expr, context);
-
-    // Bail out if the chain is just try sugar, i.e., an expression followed by
-    // any number of `?`s.
-    if chain_only_try(&subexpr_list) {
-        return rewrite_try(&parent, subexpr_list.len(), context, shape);
-    }
-    let suffix_try_num = subexpr_list.iter().take_while(|e| is_try(e)).count();
-    let prefix_try_num = subexpr_list.iter().rev().take_while(|e| is_try(e)).count();
-
-    // Parent is the first item in the chain, e.g., `foo` in `foo.bar.baz()`.
-    let parent_shape = if is_block_expr(context, &parent, "\n") {
-        match context.config.indent_style() {
-            IndentStyle::Visual => shape.visual_indent(0),
-            IndentStyle::Block => shape,
-        }
-    } else {
-        shape
-    };
-    let parent_rewrite = parent
-        .rewrite(context, parent_shape)
-        .map(|parent_rw| parent_rw + &repeat_try(prefix_try_num))?;
-    let parent_rewrite_contains_newline = parent_rewrite.contains('\n');
-    let is_small_parent = parent_rewrite.len() <= context.config.tab_spaces();
-
-    // Decide how to layout the rest of the chain. `extend` is true if we can
-    // put the first non-parent item on the same line as the parent.
-    let (nested_shape, extend) = if !parent_rewrite_contains_newline && is_continuable(&parent) {
-        (
-            chain_indent(context, shape.add_offset(parent_rewrite.len())),
-            context.config.indent_style() == IndentStyle::Visual || is_small_parent,
-        )
-    } else if is_block_expr(context, &parent, &parent_rewrite) {
-        match context.config.indent_style() {
-            // Try to put the first child on the same line with parent's last line
-            IndentStyle::Block => (parent_shape.block_indent(context.config.tab_spaces()), true),
-            // The parent is a block, so align the rest of the chain with the closing
-            // brace.
-            IndentStyle::Visual => (parent_shape, false),
-        }
-    } else {
-        (
-            chain_indent(context, shape.add_offset(parent_rewrite.len())),
-            false,
-        )
-    };
-
-    let other_child_shape = nested_shape.with_max_width(context.config);
-
-    let first_child_shape = if extend {
-        let overhead = last_line_width(&parent_rewrite);
-        let offset = trimmed_last_line_width(&parent_rewrite) + prefix_try_num;
-        match context.config.indent_style() {
-            IndentStyle::Visual => parent_shape.offset_left(overhead)?,
-            IndentStyle::Block => parent_shape.offset_left(offset)?,
-        }
-    } else {
-        other_child_shape
-    };
-    debug!(
-        "child_shapes {:?} {:?}",
-        first_child_shape, other_child_shape
-    );
-
-    let child_shape_iter = Some(first_child_shape)
-        .into_iter()
-        .chain(iter::repeat(other_child_shape));
-    let subexpr_num = subexpr_list.len();
-    let last_subexpr = &subexpr_list[suffix_try_num];
-    let subexpr_list = &subexpr_list[suffix_try_num..subexpr_num - prefix_try_num];
-    let iter = subexpr_list.iter().skip(1).rev().zip(child_shape_iter);
-    let mut rewrites = iter.map(|(e, shape)| rewrite_chain_subexpr(e, total_span, context, shape))
-        .collect::<Option<Vec<_>>>()?;
-
-    // Total of all items excluding the last.
-    let extend_last_subexpr = if is_small_parent {
-        rewrites.len() == 1 && last_line_extendable(&rewrites[0])
-    } else {
-        rewrites.is_empty() && last_line_extendable(&parent_rewrite)
-    };
-    let almost_total = if extend_last_subexpr {
-        last_line_width(&parent_rewrite)
-    } else {
-        rewrites.iter().fold(0, |a, b| a + b.len()) + parent_rewrite.len()
-    } + suffix_try_num;
-    let one_line_budget = if rewrites.is_empty() {
-        shape.width
-    } else {
-        min(shape.width, context.config.width_heuristics().chain_width)
-    };
-    let all_in_one_line = !parent_rewrite_contains_newline
-        && rewrites.iter().all(|s| !s.contains('\n'))
-        && almost_total < one_line_budget;
-    let last_shape = if rewrites.is_empty() {
-        first_child_shape
-    } else {
-        other_child_shape
-    }.sub_width(shape.rhs_overhead(context.config) + suffix_try_num)?;
-
-    // Rewrite the last child. The last child of a chain requires special treatment. We need to
-    // know whether 'overflowing' the last child make a better formatting:
-    //
-    // A chain with overflowing the last child:
-    // ```
-    // parent.child1.child2.last_child(
-    //     a,
-    //     b,
-    //     c,
-    // )
-    // ```
-    //
-    // A chain without overflowing the last child (in vertical layout):
-    // ```
-    // parent
-    //     .child1
-    //     .child2
-    //     .last_child(a, b, c)
-    // ```
-    //
-    // In particular, overflowing is effective when the last child is a method with a multi-lined
-    // block-like argument (e.g. closure):
-    // ```
-    // parent.child1.child2.last_child(|a, b, c| {
-    //     let x = foo(a, b, c);
-    //     let y = bar(a, b, c);
-    //
-    //     // ...
-    //
-    //     result
-    // })
-    // ```
-
-    // `rewrite_last` rewrites the last child on its own line. We use a closure here instead of
-    // directly calling `rewrite_chain_subexpr()` to avoid exponential blowup.
-    let rewrite_last = || rewrite_chain_subexpr(last_subexpr, total_span, context, last_shape);
-    let (last_subexpr_str, fits_single_line) = if all_in_one_line || extend_last_subexpr {
-        // First we try to 'overflow' the last child and see if it looks better than using
-        // vertical layout.
-        parent_shape.offset_left(almost_total).map(|shape| {
-            if let Some(rw) = rewrite_chain_subexpr(last_subexpr, total_span, context, shape) {
-                // We allow overflowing here only if both of the following conditions match:
-                // 1. The entire chain fits in a single line expect the last child.
-                // 2. `last_child_str.lines().count() >= 5`.
-                let line_count = rw.lines().count();
-                let fits_single_line = almost_total + first_line_width(&rw) <= one_line_budget;
-                if fits_single_line && line_count >= 5 {
-                    (Some(rw), true)
-                } else {
-                    // We could not know whether overflowing is better than using vertical layout,
-                    // just by looking at the overflowed rewrite. Now we rewrite the last child
-                    // on its own line, and compare two rewrites to choose which is better.
-                    match rewrite_last() {
-                        Some(ref new_rw) if !fits_single_line => (Some(new_rw.clone()), false),
-                        Some(ref new_rw) if new_rw.lines().count() >= line_count => {
-                            (Some(rw), fits_single_line)
-                        }
-                        new_rw @ Some(..) => (new_rw, false),
-                        _ => (Some(rw), fits_single_line),
-                    }
-                }
-            } else {
-                (rewrite_last(), false)
-            }
-        })?
-    } else {
-        (rewrite_last(), false)
-    };
-    rewrites.push(last_subexpr_str?);
-
-    let connector = if fits_single_line && !parent_rewrite_contains_newline {
-        // Yay, we can put everything on one line.
-        String::new()
-    } else {
-        // Use new lines.
-        if context.force_one_line_chain {
-            return None;
-        }
-        format!("\n{}", nested_shape.indent.to_string(context.config))
-    };
-
-    let first_connector = if is_small_parent || fits_single_line
-        || last_line_extendable(&parent_rewrite)
-        || context.config.indent_style() == IndentStyle::Visual
-    {
-        ""
-    } else {
-        connector.as_str()
-    };
-
-    let result = if is_small_parent && rewrites.len() > 1 {
-        let second_connector = if fits_single_line || rewrites[1] == "?"
-            || last_line_extendable(&rewrites[0])
-            || context.config.indent_style() == IndentStyle::Visual
-        {
-            ""
-        } else {
-            &connector
-        };
-        format!(
-            "{}{}{}{}{}",
-            parent_rewrite,
-            first_connector,
-            rewrites[0],
-            second_connector,
-            join_rewrites(&rewrites[1..], &connector)
-        )
-    } else {
-        format!(
-            "{}{}{}",
-            parent_rewrite,
-            first_connector,
-            join_rewrites(&rewrites, &connector)
-        )
-    };
-    let result = format!("{}{}", result, repeat_try(suffix_try_num));
-    if context.config.indent_style() == IndentStyle::Visual {
-        wrap_str(result, context.config.max_width(), shape)
-    } else {
-        Some(result)
-    }
-}
-
-// True if the chain is only `?`s.
-fn chain_only_try(exprs: &[ast::Expr]) -> bool {
-    exprs.iter().all(|e| {
-        if let ast::ExprKind::Try(_) = e.node {
-            true
-        } else {
-            false
-        }
-    })
-}
-
-// Try to rewrite and replace the last non-try child. Return `true` if
-// replacing succeeds.
-fn repeat_try(try_count: usize) -> String {
-    iter::repeat("?").take(try_count).collect::<String>()
-}
-
-fn rewrite_try(
-    expr: &ast::Expr,
-    try_count: usize,
-    context: &RewriteContext,
-    shape: Shape,
-) -> Option<String> {
-    let sub_expr = expr.rewrite(context, shape.sub_width(try_count)?)?;
-    Some(format!("{}{}", sub_expr, repeat_try(try_count)))
-}
-
-fn join_rewrites(rewrites: &[String], connector: &str) -> String {
-    let mut rewrite_iter = rewrites.iter();
-    let mut result = rewrite_iter.next().unwrap().clone();
-
-    for rewrite in rewrite_iter {
-        if rewrite != "?" {
-            result.push_str(connector);
-        }
-        result.push_str(&rewrite[..]);
-    }
-
-    result
-}
-
-// States whether an expression's last line exclusively consists of closing
-// parens, braces, and brackets in its idiomatic formatting.
-fn is_block_expr(context: &RewriteContext, expr: &ast::Expr, repr: &str) -> bool {
-    match expr.node {
-        ast::ExprKind::Mac(..) | ast::ExprKind::Call(..) => {
-            context.use_block_indent() && repr.contains('\n')
-        }
-        ast::ExprKind::Struct(..)
-        | ast::ExprKind::While(..)
-        | ast::ExprKind::WhileLet(..)
-        | ast::ExprKind::If(..)
-        | ast::ExprKind::IfLet(..)
-        | ast::ExprKind::Block(..)
-        | ast::ExprKind::Loop(..)
-        | ast::ExprKind::ForLoop(..)
-        | ast::ExprKind::Match(..) => repr.contains('\n'),
-        ast::ExprKind::Paren(ref expr)
-        | ast::ExprKind::Binary(_, _, ref expr)
-        | ast::ExprKind::Index(_, ref expr)
-        | ast::ExprKind::Unary(_, ref expr) => is_block_expr(context, expr, repr),
-        _ => false,
-    }
-}
-
-// Returns the root of the chain and a Vec of the prefixes of the rest of the chain.
-// E.g., for input `a.b.c` we return (`a`, [`a.b.c`, `a.b`])
-fn make_subexpr_list(expr: &ast::Expr, context: &RewriteContext) -> (ast::Expr, Vec<ast::Expr>) {
-    let mut subexpr_list = vec![expr.clone()];
-
-    while let Some(subexpr) = pop_expr_chain(subexpr_list.last().unwrap(), context) {
-        subexpr_list.push(subexpr.clone());
-    }
-
-    let parent = subexpr_list.pop().unwrap();
-    (parent, subexpr_list)
-}
-
-fn chain_indent(context: &RewriteContext, shape: Shape) -> Shape {
-    match context.config.indent_style() {
-        IndentStyle::Visual => shape.visual_indent(0),
-        IndentStyle::Block => shape
-            .block_indent(context.config.tab_spaces())
-            .with_max_width(context.config),
-    }
-}
-
-// Returns the expression's subexpression, if it exists. When the subexpr
-// is a try! macro, we'll convert it to shorthand when the option is set.
-fn pop_expr_chain(expr: &ast::Expr, context: &RewriteContext) -> Option<ast::Expr> {
-    match expr.node {
-        ast::ExprKind::MethodCall(_, ref expressions) => {
-            Some(convert_try(&expressions[0], context))
-        }
-        ast::ExprKind::TupField(ref subexpr, _)
-        | ast::ExprKind::Field(ref subexpr, _)
-        | ast::ExprKind::Try(ref subexpr) => Some(convert_try(subexpr, context)),
-        _ => None,
-    }
-}
-
-fn convert_try(expr: &ast::Expr, context: &RewriteContext) -> ast::Expr {
-    match expr.node {
-        ast::ExprKind::Mac(ref mac) if context.config.use_try_shorthand() => {
-            if let Some(subexpr) = convert_try_mac(mac, context) {
-                subexpr
-            } else {
-                expr.clone()
-            }
-        }
-        _ => expr.clone(),
-    }
-}
-
-// Rewrite the last element in the chain `expr`. E.g., given `a.b.c` we rewrite
-// `.c`.
-fn rewrite_chain_subexpr(
-    expr: &ast::Expr,
-    span: Span,
-    context: &RewriteContext,
-    shape: Shape,
-) -> Option<String> {
-    let rewrite_element = |expr_str: String| {
-        if expr_str.len() <= shape.width {
-            Some(expr_str)
-        } else {
-            None
-        }
-    };
-
-    match expr.node {
-        ast::ExprKind::MethodCall(ref segment, ref expressions) => {
-            let types = match segment.parameters {
-                Some(ref params) => match **params {
-                    ast::PathParameters::AngleBracketed(ref data) => &data.types[..],
-                    _ => &[],
-                },
-                _ => &[],
-            };
-            rewrite_method_call(segment.identifier, types, expressions, span, context, shape)
-        }
-        ast::ExprKind::Field(_, ref field) => rewrite_element(format!(".{}", field.node)),
-        ast::ExprKind::TupField(ref expr, ref field) => {
-            let space = match expr.node {
-                ast::ExprKind::TupField(..) => " ",
-                _ => "",
-            };
-            rewrite_element(format!("{}.{}", space, field.node))
-        }
-        ast::ExprKind::Try(_) => rewrite_element(String::from("?")),
-        _ => unreachable!(),
-    }
-}
-
-// Determines if we can continue formatting a given expression on the same line.
-fn is_continuable(expr: &ast::Expr) -> bool {
-    match expr.node {
-        ast::ExprKind::Path(..) => true,
-        _ => false,
-    }
-}
-
-fn is_try(expr: &ast::Expr) -> bool {
-    match expr.node {
-        ast::ExprKind::Try(..) => true,
-        _ => false,
-    }
-}
-
-fn rewrite_method_call(
-    method_name: ast::Ident,
-    types: &[ptr::P<ast::Ty>],
-    args: &[ptr::P<ast::Expr>],
-    span: Span,
-    context: &RewriteContext,
-    shape: Shape,
-) -> Option<String> {
-    let (lo, type_str) = if types.is_empty() {
-        (args[0].span.hi(), String::new())
-    } else {
-        let type_list = types
-            .iter()
-            .map(|ty| ty.rewrite(context, shape))
-            .collect::<Option<Vec<_>>>()?;
-
-        let type_str =
-            if context.config.spaces_within_parens_and_brackets() && !type_list.is_empty() {
-                format!("::< {} >", type_list.join(", "))
-            } else {
-                format!("::<{}>", type_list.join(", "))
-            };
-
-        (types.last().unwrap().span.hi(), type_str)
-    };
-
-    let callee_str = format!(".{}{}", method_name, type_str);
-    let span = mk_sp(lo, span.hi());
-
-    rewrite_call(context, &callee_str, &args[1..], span, shape)
-}
diff --git a/src/checkstyle.rs b/src/checkstyle.rs
deleted file mode 100644
index 7f6e650ad22..00000000000
--- a/src/checkstyle.rs
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::io::{self, Write};
-use std::path::Path;
-
-use config::WriteMode;
-use rustfmt_diff::{DiffLine, Mismatch};
-
-pub fn output_header<T>(out: &mut T, mode: WriteMode) -> Result<(), io::Error>
-where
-    T: Write,
-{
-    if mode == WriteMode::Checkstyle {
-        let mut xml_heading = String::new();
-        xml_heading.push_str("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
-        xml_heading.push_str("\n");
-        xml_heading.push_str("<checkstyle version=\"4.3\">");
-        write!(out, "{}", xml_heading)?;
-    }
-    Ok(())
-}
-
-pub fn output_footer<T>(out: &mut T, mode: WriteMode) -> Result<(), io::Error>
-where
-    T: Write,
-{
-    if mode == WriteMode::Checkstyle {
-        let mut xml_tail = String::new();
-        xml_tail.push_str("</checkstyle>\n");
-        write!(out, "{}", xml_tail)?;
-    }
-    Ok(())
-}
-
-pub fn output_checkstyle_file<T>(
-    mut writer: T,
-    filename: &Path,
-    diff: Vec<Mismatch>,
-) -> Result<(), io::Error>
-where
-    T: Write,
-{
-    write!(writer, "<file name=\"{}\">", filename.display())?;
-    for mismatch in diff {
-        for line in mismatch.lines {
-            // Do nothing with `DiffLine::Context` and `DiffLine::Resulting`.
-            if let DiffLine::Expected(ref str) = line {
-                let message = xml_escape_str(str);
-                write!(
-                    writer,
-                    "<error line=\"{}\" severity=\"warning\" message=\"Should be `{}`\" \
-                     />",
-                    mismatch.line_number, message
-                )?;
-            }
-        }
-    }
-    write!(writer, "</file>")?;
-    Ok(())
-}
-
-// Convert special characters into XML entities.
-// This is needed for checkstyle output.
-fn xml_escape_str(string: &str) -> String {
-    let mut out = String::new();
-    for c in string.chars() {
-        match c {
-            '<' => out.push_str("&lt;"),
-            '>' => out.push_str("&gt;"),
-            '"' => out.push_str("&quot;"),
-            '\'' => out.push_str("&apos;"),
-            '&' => out.push_str("&amp;"),
-            _ => out.push(c),
-        }
-    }
-    out
-}
diff --git a/src/closures.rs b/src/closures.rs
deleted file mode 100644
index 61287543da9..00000000000
--- a/src/closures.rs
+++ /dev/null
@@ -1,392 +0,0 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use syntax::{ast, ptr};
-use syntax::codemap::Span;
-use syntax::parse::classify;
-
-use codemap::SpanUtils;
-use expr::{block_contains_comment, is_simple_block, is_unsafe_block, rewrite_cond, ToExpr};
-use items::{span_hi_for_arg, span_lo_for_arg};
-use lists::{definitive_tactic, itemize_list, write_list, DefinitiveListTactic, ListFormatting,
-            ListTactic, Separator, SeparatorPlace, SeparatorTactic};
-use rewrite::{Rewrite, RewriteContext};
-use shape::Shape;
-use utils::{last_line_width, left_most_sub_expr, stmt_expr};
-
-// This module is pretty messy because of the rules around closures and blocks:
-// FIXME - the below is probably no longer true in full.
-//   * if there is a return type, then there must be braces,
-//   * given a closure with braces, whether that is parsed to give an inner block
-//     or not depends on if there is a return type and if there are statements
-//     in that block,
-//   * if the first expression in the body ends with a block (i.e., is a
-//     statement without needing a semi-colon), then adding or removing braces
-//     can change whether it is treated as an expression or statement.
-
-pub fn rewrite_closure(
-    capture: ast::CaptureBy,
-    movability: ast::Movability,
-    fn_decl: &ast::FnDecl,
-    body: &ast::Expr,
-    span: Span,
-    context: &RewriteContext,
-    shape: Shape,
-) -> Option<String> {
-    debug!("rewrite_closure {:?}", body);
-
-    let (prefix, extra_offset) =
-        rewrite_closure_fn_decl(capture, movability, fn_decl, body, span, context, shape)?;
-    // 1 = space between `|...|` and body.
-    let body_shape = shape.offset_left(extra_offset)?;
-
-    if let ast::ExprKind::Block(ref block) = body.node {
-        // The body of the closure is an empty block.
-        if block.stmts.is_empty() && !block_contains_comment(block, context.codemap) {
-            return Some(format!("{} {{}}", prefix));
-        }
-
-        let result = match fn_decl.output {
-            ast::FunctionRetTy::Default(_) => {
-                try_rewrite_without_block(body, &prefix, context, shape, body_shape)
-            }
-            _ => None,
-        };
-
-        result.or_else(|| {
-            // Either we require a block, or tried without and failed.
-            rewrite_closure_block(block, &prefix, context, body_shape)
-        })
-    } else {
-        rewrite_closure_expr(body, &prefix, context, body_shape).or_else(|| {
-            // The closure originally had a non-block expression, but we can't fit on
-            // one line, so we'll insert a block.
-            rewrite_closure_with_block(body, &prefix, context, body_shape)
-        })
-    }
-}
-
-fn try_rewrite_without_block(
-    expr: &ast::Expr,
-    prefix: &str,
-    context: &RewriteContext,
-    shape: Shape,
-    body_shape: Shape,
-) -> Option<String> {
-    let expr = get_inner_expr(expr, prefix, context);
-
-    if is_block_closure_forced(context, expr) {
-        rewrite_closure_with_block(expr, prefix, context, shape)
-    } else {
-        rewrite_closure_expr(expr, prefix, context, body_shape)
-    }
-}
-
-fn get_inner_expr<'a>(
-    expr: &'a ast::Expr,
-    prefix: &str,
-    context: &RewriteContext,
-) -> &'a ast::Expr {
-    if let ast::ExprKind::Block(ref block) = expr.node {
-        if !needs_block(block, prefix, context) {
-            // block.stmts.len() == 1
-            if let Some(expr) = stmt_expr(&block.stmts[0]) {
-                return get_inner_expr(expr, prefix, context);
-            }
-        }
-    }
-
-    expr
-}
-
-// Figure out if a block is necessary.
-fn needs_block(block: &ast::Block, prefix: &str, context: &RewriteContext) -> bool {
-    is_unsafe_block(block) || block.stmts.len() > 1
-        || block_contains_comment(block, context.codemap) || prefix.contains('\n')
-}
-
-// Rewrite closure with a single expression wrapping its body with block.
-fn rewrite_closure_with_block(
-    body: &ast::Expr,
-    prefix: &str,
-    context: &RewriteContext,
-    shape: Shape,
-) -> Option<String> {
-    let left_most = left_most_sub_expr(body);
-    let veto_block = left_most != body && !classify::expr_requires_semi_to_be_stmt(left_most);
-    if veto_block {
-        return None;
-    }
-
-    let block = ast::Block {
-        stmts: vec![
-            ast::Stmt {
-                id: ast::NodeId::new(0),
-                node: ast::StmtKind::Expr(ptr::P(body.clone())),
-                span: body.span,
-            },
-        ],
-        id: ast::NodeId::new(0),
-        rules: ast::BlockCheckMode::Default,
-        span: body.span,
-        recovered: false,
-    };
-    let block = ::expr::rewrite_block_with_visitor(context, "", &block, shape, false)?;
-    Some(format!("{} {}", prefix, block))
-}
-
-// Rewrite closure with a single expression without wrapping its body with block.
-fn rewrite_closure_expr(
-    expr: &ast::Expr,
-    prefix: &str,
-    context: &RewriteContext,
-    shape: Shape,
-) -> Option<String> {
-    fn allow_multi_line(expr: &ast::Expr) -> bool {
-        match expr.node {
-            ast::ExprKind::Match(..)
-            | ast::ExprKind::Block(..)
-            | ast::ExprKind::Catch(..)
-            | ast::ExprKind::Loop(..)
-            | ast::ExprKind::Struct(..) => true,
-
-            ast::ExprKind::AddrOf(_, ref expr)
-            | ast::ExprKind::Box(ref expr)
-            | ast::ExprKind::Try(ref expr)
-            | ast::ExprKind::Unary(_, ref expr)
-            | ast::ExprKind::Cast(ref expr, _) => allow_multi_line(expr),
-
-            _ => false,
-        }
-    }
-
-    // When rewriting closure's body without block, we require it to fit in a single line
-    // unless it is a block-like expression or we are inside macro call.
-    let veto_multiline = (!allow_multi_line(expr) && !context.inside_macro)
-        || context.config.force_multiline_blocks();
-    expr.rewrite(context, shape)
-        .and_then(|rw| {
-            if veto_multiline && rw.contains('\n') {
-                None
-            } else {
-                Some(rw)
-            }
-        })
-        .map(|rw| format!("{} {}", prefix, rw))
-}
-
-// Rewrite closure whose body is block.
-fn rewrite_closure_block(
-    block: &ast::Block,
-    prefix: &str,
-    context: &RewriteContext,
-    shape: Shape,
-) -> Option<String> {
-    Some(format!("{} {}", prefix, block.rewrite(context, shape)?))
-}
-
-// Return type is (prefix, extra_offset)
-fn rewrite_closure_fn_decl(
-    capture: ast::CaptureBy,
-    movability: ast::Movability,
-    fn_decl: &ast::FnDecl,
-    body: &ast::Expr,
-    span: Span,
-    context: &RewriteContext,
-    shape: Shape,
-) -> Option<(String, usize)> {
-    let mover = if capture == ast::CaptureBy::Value {
-        "move "
-    } else {
-        ""
-    };
-
-    let immovable = if movability == ast::Movability::Static {
-        "static "
-    } else {
-        ""
-    };
-    // 4 = "|| {".len(), which is overconservative when the closure consists of
-    // a single expression.
-    let nested_shape = shape
-        .shrink_left(mover.len() + immovable.len())?
-        .sub_width(4)?;
-
-    // 1 = |
-    let argument_offset = nested_shape.indent + 1;
-    let arg_shape = nested_shape.offset_left(1)?.visual_indent(0);
-    let ret_str = fn_decl.output.rewrite(context, arg_shape)?;
-
-    let arg_items = itemize_list(
-        context.codemap,
-        fn_decl.inputs.iter(),
-        "|",
-        ",",
-        |arg| span_lo_for_arg(arg),
-        |arg| span_hi_for_arg(context, arg),
-        |arg| arg.rewrite(context, arg_shape),
-        context.codemap.span_after(span, "|"),
-        body.span.lo(),
-        false,
-    );
-    let item_vec = arg_items.collect::<Vec<_>>();
-    // 1 = space between arguments and return type.
-    let horizontal_budget = nested_shape
-        .width
-        .checked_sub(ret_str.len() + 1)
-        .unwrap_or(0);
-    let tactic = definitive_tactic(
-        &item_vec,
-        ListTactic::HorizontalVertical,
-        Separator::Comma,
-        horizontal_budget,
-    );
-    let arg_shape = match tactic {
-        DefinitiveListTactic::Horizontal => arg_shape.sub_width(ret_str.len() + 1)?,
-        _ => arg_shape,
-    };
-
-    let fmt = ListFormatting {
-        tactic,
-        separator: ",",
-        trailing_separator: SeparatorTactic::Never,
-        separator_place: SeparatorPlace::Back,
-        shape: arg_shape,
-        ends_with_newline: false,
-        preserve_newline: true,
-        config: context.config,
-    };
-    let list_str = write_list(&item_vec, &fmt)?;
-    let mut prefix = format!("{}{}|{}|", immovable, mover, list_str);
-
-    if !ret_str.is_empty() {
-        if prefix.contains('\n') {
-            prefix.push('\n');
-            prefix.push_str(&argument_offset.to_string(context.config));
-        } else {
-            prefix.push(' ');
-        }
-        prefix.push_str(&ret_str);
-    }
-    // 1 = space between `|...|` and body.
-    let extra_offset = last_line_width(&prefix) + 1;
-
-    Some((prefix, extra_offset))
-}
-
-// Rewriting closure which is placed at the end of the function call's arg.
-// Returns `None` if the reformatted closure 'looks bad'.
-pub fn rewrite_last_closure(
-    context: &RewriteContext,
-    expr: &ast::Expr,
-    shape: Shape,
-) -> Option<String> {
-    if let ast::ExprKind::Closure(capture, movability, ref fn_decl, ref body, _) = expr.node {
-        let body = match body.node {
-            ast::ExprKind::Block(ref block)
-                if !is_unsafe_block(block) && is_simple_block(block, context.codemap) =>
-            {
-                stmt_expr(&block.stmts[0]).unwrap_or(body)
-            }
-            _ => body,
-        };
-        let (prefix, extra_offset) = rewrite_closure_fn_decl(
-            capture,
-            movability,
-            fn_decl,
-            body,
-            expr.span,
-            context,
-            shape,
-        )?;
-        // If the closure goes multi line before its body, do not overflow the closure.
-        if prefix.contains('\n') {
-            return None;
-        }
-
-        let body_shape = shape.offset_left(extra_offset)?;
-
-        // We force to use block for the body of the closure for certain kinds of expressions.
-        if is_block_closure_forced(context, body) {
-            return rewrite_closure_with_block(body, &prefix, context, body_shape).and_then(
-                |body_str| {
-                    // If the expression can fit in a single line, we need not force block closure.
-                    if body_str.lines().count() <= 7 {
-                        match rewrite_closure_expr(body, &prefix, context, shape) {
-                            Some(ref single_line_body_str)
-                                if !single_line_body_str.contains('\n') =>
-                            {
-                                Some(single_line_body_str.clone())
-                            }
-                            _ => Some(body_str),
-                        }
-                    } else {
-                        Some(body_str)
-                    }
-                },
-            );
-        }
-
-        // When overflowing the closure which consists of a single control flow expression,
-        // force to use block if its condition uses multi line.
-        let is_multi_lined_cond = rewrite_cond(context, body, body_shape)
-            .map(|cond| cond.contains('\n') || cond.len() > body_shape.width)
-            .unwrap_or(false);
-        if is_multi_lined_cond {
-            return rewrite_closure_with_block(body, &prefix, context, body_shape);
-        }
-
-        // Seems fine, just format the closure in usual manner.
-        return expr.rewrite(context, shape);
-    }
-    None
-}
-
-/// Returns true if the given vector of arguments has more than one `ast::ExprKind::Closure`.
-pub fn args_have_many_closure<T>(args: &[&T]) -> bool
-where
-    T: ToExpr,
-{
-    args.iter()
-        .filter(|arg| {
-            arg.to_expr()
-                .map(|e| match e.node {
-                    ast::ExprKind::Closure(..) => true,
-                    _ => false,
-                })
-                .unwrap_or(false)
-        })
-        .count() > 1
-}
-
-fn is_block_closure_forced(context: &RewriteContext, expr: &ast::Expr) -> bool {
-    // If we are inside macro, we do not want to add or remove block from closure body.
-    if context.inside_macro {
-        false
-    } else {
-        is_block_closure_forced_inner(expr)
-    }
-}
-
-fn is_block_closure_forced_inner(expr: &ast::Expr) -> bool {
-    match expr.node {
-        ast::ExprKind::If(..)
-        | ast::ExprKind::IfLet(..)
-        | ast::ExprKind::While(..)
-        | ast::ExprKind::WhileLet(..)
-        | ast::ExprKind::ForLoop(..) => true,
-        ast::ExprKind::AddrOf(_, ref expr)
-        | ast::ExprKind::Box(ref expr)
-        | ast::ExprKind::Try(ref expr)
-        | ast::ExprKind::Unary(_, ref expr)
-        | ast::ExprKind::Cast(ref expr, _) => is_block_closure_forced_inner(expr),
-        _ => false,
-    }
-}
diff --git a/src/codemap.rs b/src/codemap.rs
deleted file mode 100644
index d74d24439d9..00000000000
--- a/src/codemap.rs
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! This module contains utilities that work with the `CodeMap` from `libsyntax` / `syntex_syntax`.
-//! This includes extension traits and methods for looking up spans and line ranges for AST nodes.
-
-use std::rc::Rc;
-
-use syntax::codemap::{BytePos, CodeMap, FileMap, FileName, Span};
-
-use comment::FindUncommented;
-
-/// A range of lines in a file, inclusive of both ends.
-pub struct LineRange {
-    pub file: Rc<FileMap>,
-    pub lo: usize,
-    pub hi: usize,
-}
-
-impl LineRange {
-    pub fn file_name(&self) -> &FileName {
-        &self.file.name
-    }
-}
-
-pub trait SpanUtils {
-    fn span_after(&self, original: Span, needle: &str) -> BytePos;
-    fn span_after_last(&self, original: Span, needle: &str) -> BytePos;
-    fn span_before(&self, original: Span, needle: &str) -> BytePos;
-    fn opt_span_after(&self, original: Span, needle: &str) -> Option<BytePos>;
-}
-
-pub trait LineRangeUtils {
-    /// Returns the `LineRange` that corresponds to `span` in `self`.
-    ///
-    /// # Panics
-    ///
-    /// Panics if `span` crosses a file boundary, which shouldn't happen.
-    fn lookup_line_range(&self, span: Span) -> LineRange;
-}
-
-impl SpanUtils for CodeMap {
-    fn span_after(&self, original: Span, needle: &str) -> BytePos {
-        let snippet = self.span_to_snippet(original).expect("Bad snippet");
-        let offset = snippet.find_uncommented(needle).expect("Bad offset") + needle.len();
-
-        original.lo() + BytePos(offset as u32)
-    }
-
-    fn span_after_last(&self, original: Span, needle: &str) -> BytePos {
-        let snippet = self.span_to_snippet(original).unwrap();
-        let mut offset = 0;
-
-        while let Some(additional_offset) = snippet[offset..].find_uncommented(needle) {
-            offset += additional_offset + needle.len();
-        }
-
-        original.lo() + BytePos(offset as u32)
-    }
-
-    fn span_before(&self, original: Span, needle: &str) -> BytePos {
-        let snippet = self.span_to_snippet(original).unwrap();
-        let offset = snippet.find_uncommented(needle).unwrap();
-
-        original.lo() + BytePos(offset as u32)
-    }
-
-    fn opt_span_after(&self, original: Span, needle: &str) -> Option<BytePos> {
-        let snippet = self.span_to_snippet(original).ok()?;
-        let offset = snippet.find_uncommented(needle)? + needle.len();
-
-        Some(original.lo() + BytePos(offset as u32))
-    }
-}
-
-impl LineRangeUtils for CodeMap {
-    fn lookup_line_range(&self, span: Span) -> LineRange {
-        let lo = self.lookup_char_pos(span.lo());
-        let hi = self.lookup_char_pos(span.hi());
-
-        assert_eq!(
-            lo.file.name, hi.file.name,
-            "span crossed file boundary: lo: {:?}, hi: {:?}",
-            lo, hi
-        );
-
-        LineRange {
-            file: lo.file.clone(),
-            lo: lo.line,
-            hi: hi.line,
-        }
-    }
-}
diff --git a/src/comment.rs b/src/comment.rs
deleted file mode 100644
index 9c0322bcaeb..00000000000
--- a/src/comment.rs
+++ /dev/null
@@ -1,1234 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Formatting and tools for comments.
-
-use std::{self, iter};
-
-use syntax::codemap::Span;
-
-use config::Config;
-use rewrite::RewriteContext;
-use shape::{Indent, Shape};
-use string::{rewrite_string, StringFormat};
-use utils::{count_newlines, first_line_width, last_line_width};
-
-fn is_custom_comment(comment: &str) -> bool {
-    if !comment.starts_with("//") {
-        false
-    } else if let Some(c) = comment.chars().nth(2) {
-        !c.is_alphanumeric() && !c.is_whitespace()
-    } else {
-        false
-    }
-}
-
-#[derive(Copy, Clone, PartialEq, Eq)]
-pub enum CommentStyle<'a> {
-    DoubleSlash,
-    TripleSlash,
-    Doc,
-    SingleBullet,
-    DoubleBullet,
-    Exclamation,
-    Custom(&'a str),
-}
-
-fn custom_opener(s: &str) -> &str {
-    s.lines().next().map_or("", |first_line| {
-        first_line
-            .find(' ')
-            .map_or(first_line, |space_index| &first_line[0..space_index + 1])
-    })
-}
-
-impl<'a> CommentStyle<'a> {
-    pub fn opener(&self) -> &'a str {
-        match *self {
-            CommentStyle::DoubleSlash => "// ",
-            CommentStyle::TripleSlash => "/// ",
-            CommentStyle::Doc => "//! ",
-            CommentStyle::SingleBullet => "/* ",
-            CommentStyle::DoubleBullet => "/** ",
-            CommentStyle::Exclamation => "/*! ",
-            CommentStyle::Custom(opener) => opener,
-        }
-    }
-
-    pub fn closer(&self) -> &'a str {
-        match *self {
-            CommentStyle::DoubleSlash
-            | CommentStyle::TripleSlash
-            | CommentStyle::Custom(..)
-            | CommentStyle::Doc => "",
-            CommentStyle::DoubleBullet => " **/",
-            CommentStyle::SingleBullet | CommentStyle::Exclamation => " */",
-        }
-    }
-
-    pub fn line_start(&self) -> &'a str {
-        match *self {
-            CommentStyle::DoubleSlash => "// ",
-            CommentStyle::TripleSlash => "/// ",
-            CommentStyle::Doc => "//! ",
-            CommentStyle::SingleBullet | CommentStyle::Exclamation => " * ",
-            CommentStyle::DoubleBullet => " ** ",
-            CommentStyle::Custom(opener) => opener,
-        }
-    }
-
-    pub fn to_str_tuplet(&self) -> (&'a str, &'a str, &'a str) {
-        (self.opener(), self.closer(), self.line_start())
-    }
-
-    pub fn line_with_same_comment_style(&self, line: &str, normalize_comments: bool) -> bool {
-        match *self {
-            CommentStyle::DoubleSlash | CommentStyle::TripleSlash | CommentStyle::Doc => {
-                line.trim_left().starts_with(self.line_start().trim_left())
-                    || comment_style(line, normalize_comments) == *self
-            }
-            CommentStyle::DoubleBullet | CommentStyle::SingleBullet | CommentStyle::Exclamation => {
-                line.trim_left().starts_with(self.closer().trim_left())
-                    || line.trim_left().starts_with(self.line_start().trim_left())
-                    || comment_style(line, normalize_comments) == *self
-            }
-            CommentStyle::Custom(opener) => line.trim_left().starts_with(opener.trim_right()),
-        }
-    }
-}
-
-fn comment_style(orig: &str, normalize_comments: bool) -> CommentStyle {
-    if !normalize_comments {
-        if orig.starts_with("/**") && !orig.starts_with("/**/") {
-            CommentStyle::DoubleBullet
-        } else if orig.starts_with("/*!") {
-            CommentStyle::Exclamation
-        } else if orig.starts_with("/*") {
-            CommentStyle::SingleBullet
-        } else if orig.starts_with("///") && orig.chars().nth(3).map_or(true, |c| c != '/') {
-            CommentStyle::TripleSlash
-        } else if orig.starts_with("//!") {
-            CommentStyle::Doc
-        } else if is_custom_comment(orig) {
-            CommentStyle::Custom(custom_opener(orig))
-        } else {
-            CommentStyle::DoubleSlash
-        }
-    } else if (orig.starts_with("///") && orig.chars().nth(3).map_or(true, |c| c != '/'))
-        || (orig.starts_with("/**") && !orig.starts_with("/**/"))
-    {
-        CommentStyle::TripleSlash
-    } else if orig.starts_with("//!") || orig.starts_with("/*!") {
-        CommentStyle::Doc
-    } else if is_custom_comment(orig) {
-        CommentStyle::Custom(custom_opener(orig))
-    } else {
-        CommentStyle::DoubleSlash
-    }
-}
-
-/// Combine `prev_str` and `next_str` into a single `String`. `span` may contain
-/// comments between two strings. If there are such comments, then that will be
-/// recovered. If `allow_extend` is true and there is no comment between the two
-/// strings, then they will be put on a single line as long as doing so does not
-/// exceed max width.
-pub fn combine_strs_with_missing_comments(
-    context: &RewriteContext,
-    prev_str: &str,
-    next_str: &str,
-    span: Span,
-    shape: Shape,
-    allow_extend: bool,
-) -> Option<String> {
-    let mut allow_one_line = !prev_str.contains('\n') && !next_str.contains('\n');
-    let first_sep = if prev_str.is_empty() || next_str.is_empty() {
-        ""
-    } else {
-        " "
-    };
-    let mut one_line_width =
-        last_line_width(prev_str) + first_line_width(next_str) + first_sep.len();
-
-    let indent_str = shape.indent.to_string(context.config);
-    let missing_comment = rewrite_missing_comment(span, shape, context)?;
-
-    if missing_comment.is_empty() {
-        if allow_extend && prev_str.len() + first_sep.len() + next_str.len() <= shape.width {
-            return Some(format!("{}{}{}", prev_str, first_sep, next_str));
-        } else {
-            let sep = if prev_str.is_empty() {
-                String::new()
-            } else {
-                String::from("\n") + &indent_str
-            };
-            return Some(format!("{}{}{}", prev_str, sep, next_str));
-        }
-    }
-
-    // We have a missing comment between the first expression and the second expression.
-
-    // Peek the the original source code and find out whether there is a newline between the first
-    // expression and the second expression or the missing comment. We will preserve the original
-    // layout whenever possible.
-    let original_snippet = context.snippet(span);
-    let prefer_same_line = if let Some(pos) = original_snippet.chars().position(|c| c == '/') {
-        !original_snippet[..pos].contains('\n')
-    } else {
-        !original_snippet.contains('\n')
-    };
-
-    one_line_width -= first_sep.len();
-    let first_sep = if prev_str.is_empty() || missing_comment.is_empty() {
-        String::new()
-    } else {
-        let one_line_width = last_line_width(prev_str) + first_line_width(&missing_comment) + 1;
-        if prefer_same_line && one_line_width <= shape.width {
-            String::from(" ")
-        } else {
-            format!("\n{}", indent_str)
-        }
-    };
-    let second_sep = if missing_comment.is_empty() || next_str.is_empty() {
-        String::new()
-    } else if missing_comment.starts_with("//") {
-        format!("\n{}", indent_str)
-    } else {
-        one_line_width += missing_comment.len() + first_sep.len() + 1;
-        allow_one_line &= !missing_comment.starts_with("//") && !missing_comment.contains('\n');
-        if prefer_same_line && allow_one_line && one_line_width <= shape.width {
-            String::from(" ")
-        } else {
-            format!("\n{}", indent_str)
-        }
-    };
-    Some(format!(
-        "{}{}{}{}{}",
-        prev_str, first_sep, missing_comment, second_sep, next_str,
-    ))
-}
-
-pub fn rewrite_comment(
-    orig: &str,
-    block_style: bool,
-    shape: Shape,
-    config: &Config,
-) -> Option<String> {
-    // If there are lines without a starting sigil, we won't format them correctly
-    // so in that case we won't even re-align (if !config.normalize_comments()) and
-    // we should stop now.
-    let num_bare_lines = orig.lines()
-        .map(|line| line.trim())
-        .filter(|l| !(l.starts_with('*') || l.starts_with("//") || l.starts_with("/*")))
-        .count();
-    if num_bare_lines > 0 && !config.normalize_comments() {
-        return Some(orig.to_owned());
-    }
-    if !config.normalize_comments() && !config.wrap_comments() {
-        return light_rewrite_comment(orig, shape.indent, config);
-    }
-
-    identify_comment(orig, block_style, shape, config)
-}
-
-fn identify_comment(
-    orig: &str,
-    block_style: bool,
-    shape: Shape,
-    config: &Config,
-) -> Option<String> {
-    let style = comment_style(orig, false);
-    let first_group = orig.lines()
-        .take_while(|l| style.line_with_same_comment_style(l, false))
-        .collect::<Vec<_>>()
-        .join("\n");
-    let rest = orig.lines()
-        .skip(first_group.lines().count())
-        .collect::<Vec<_>>()
-        .join("\n");
-
-    let first_group_str = rewrite_comment_inner(&first_group, block_style, style, shape, config)?;
-    if rest.is_empty() {
-        Some(first_group_str)
-    } else {
-        identify_comment(&rest, block_style, shape, config).map(|rest_str| {
-            format!(
-                "{}\n{}{}",
-                first_group_str,
-                shape.indent.to_string(config),
-                rest_str
-            )
-        })
-    }
-}
-
-fn rewrite_comment_inner(
-    orig: &str,
-    block_style: bool,
-    style: CommentStyle,
-    shape: Shape,
-    config: &Config,
-) -> Option<String> {
-    let (opener, closer, line_start) = if block_style {
-        CommentStyle::SingleBullet.to_str_tuplet()
-    } else {
-        comment_style(orig, config.normalize_comments()).to_str_tuplet()
-    };
-
-    let max_chars = shape
-        .width
-        .checked_sub(closer.len() + opener.len())
-        .unwrap_or(1);
-    let indent_str = shape.indent.to_string(config);
-    let fmt_indent = shape.indent + (opener.len() - line_start.len());
-    let mut fmt = StringFormat {
-        opener: "",
-        closer: "",
-        line_start,
-        line_end: "",
-        shape: Shape::legacy(max_chars, fmt_indent),
-        trim_end: true,
-        config,
-    };
-
-    let line_breaks = count_newlines(orig.trim_right());
-    let lines = orig.lines()
-        .enumerate()
-        .map(|(i, mut line)| {
-            line = line.trim();
-            // Drop old closer.
-            if i == line_breaks && line.ends_with("*/") && !line.starts_with("//") {
-                line = line[..(line.len() - 2)].trim_right();
-            }
-
-            line
-        })
-        .map(|s| left_trim_comment_line(s, &style))
-        .map(|(line, has_leading_whitespace)| {
-            if orig.starts_with("/*") && line_breaks == 0 {
-                (
-                    line.trim_left(),
-                    has_leading_whitespace || config.normalize_comments(),
-                )
-            } else {
-                (line, has_leading_whitespace || config.normalize_comments())
-            }
-        });
-
-    let mut result = String::with_capacity(orig.len() * 2);
-    result.push_str(opener);
-    let mut code_block_buffer = String::with_capacity(128);
-    let mut is_prev_line_multi_line = false;
-    let mut inside_code_block = false;
-    let comment_line_separator = format!("\n{}{}", indent_str, line_start);
-    let join_code_block_with_comment_line_separator = |s: &str| {
-        let mut result = String::with_capacity(s.len() + 128);
-        let mut iter = s.lines().peekable();
-        while let Some(line) = iter.next() {
-            result.push_str(line);
-            result.push_str(match iter.peek() {
-                Some(next_line) if next_line.is_empty() => comment_line_separator.trim_right(),
-                Some(..) => &comment_line_separator,
-                None => "",
-            });
-        }
-        result
-    };
-
-    for (i, (line, has_leading_whitespace)) in lines.enumerate() {
-        let is_last = i == count_newlines(orig);
-
-        if inside_code_block {
-            if line.starts_with("```") {
-                inside_code_block = false;
-                result.push_str(&comment_line_separator);
-                let code_block = ::format_code_block(&code_block_buffer, config)
-                    .unwrap_or_else(|| code_block_buffer.to_owned());
-                result.push_str(&join_code_block_with_comment_line_separator(&code_block));
-                code_block_buffer.clear();
-                result.push_str(&comment_line_separator);
-                result.push_str(line);
-            } else {
-                code_block_buffer.push_str(line);
-                code_block_buffer.push('\n');
-            }
-
-            continue;
-        } else {
-            inside_code_block = line.starts_with("```");
-
-            if result == opener {
-                let force_leading_whitespace = opener == "/* " && count_newlines(orig) == 0;
-                if !has_leading_whitespace && !force_leading_whitespace && result.ends_with(' ') {
-                    result.pop();
-                }
-                if line.is_empty() {
-                    continue;
-                }
-            } else if is_prev_line_multi_line && !line.is_empty() {
-                result.push(' ')
-            } else if is_last && !closer.is_empty() && line.is_empty() {
-                result.push('\n');
-                result.push_str(&indent_str);
-            } else {
-                result.push_str(&comment_line_separator);
-                if !has_leading_whitespace && result.ends_with(' ') {
-                    result.pop();
-                }
-            }
-        }
-
-        if config.wrap_comments() && line.len() > fmt.shape.width && !has_url(line) {
-            match rewrite_string(line, &fmt, Some(max_chars)) {
-                Some(ref s) => {
-                    is_prev_line_multi_line = s.contains('\n');
-                    result.push_str(s);
-                }
-                None if is_prev_line_multi_line => {
-                    // We failed to put the current `line` next to the previous `line`.
-                    // Remove the trailing space, then start rewrite on the next line.
-                    result.pop();
-                    result.push_str(&comment_line_separator);
-                    fmt.shape = Shape::legacy(max_chars, fmt_indent);
-                    match rewrite_string(line, &fmt, Some(max_chars)) {
-                        Some(ref s) => {
-                            is_prev_line_multi_line = s.contains('\n');
-                            result.push_str(s);
-                        }
-                        None => {
-                            is_prev_line_multi_line = false;
-                            result.push_str(line);
-                        }
-                    }
-                }
-                None => {
-                    is_prev_line_multi_line = false;
-                    result.push_str(line);
-                }
-            }
-
-            fmt.shape = if is_prev_line_multi_line {
-                // 1 = " "
-                let offset = 1 + last_line_width(&result) - line_start.len();
-                Shape {
-                    width: max_chars.checked_sub(offset).unwrap_or(0),
-                    indent: fmt_indent,
-                    offset: fmt.shape.offset + offset,
-                }
-            } else {
-                Shape::legacy(max_chars, fmt_indent)
-            };
-        } else {
-            if line.is_empty() && result.ends_with(' ') && !is_last {
-                // Remove space if this is an empty comment or a doc comment.
-                result.pop();
-            }
-            result.push_str(line);
-            fmt.shape = Shape::legacy(max_chars, fmt_indent);
-            is_prev_line_multi_line = false;
-        }
-    }
-
-    result.push_str(closer);
-    if result == opener && result.ends_with(' ') {
-        // Trailing space.
-        result.pop();
-    }
-
-    Some(result)
-}
-
-/// Returns true if the given string MAY include URLs or alike.
-fn has_url(s: &str) -> bool {
-    // This function may return false positive, but should get its job done in most cases.
-    s.contains("https://") || s.contains("http://") || s.contains("ftp://") || s.contains("file://")
-}
-
-/// Given the span, rewrite the missing comment inside it if available.
-/// Note that the given span must only include comments (or leading/trailing whitespaces).
-pub fn rewrite_missing_comment(
-    span: Span,
-    shape: Shape,
-    context: &RewriteContext,
-) -> Option<String> {
-    let missing_snippet = context.snippet(span);
-    let trimmed_snippet = missing_snippet.trim();
-    if !trimmed_snippet.is_empty() {
-        rewrite_comment(trimmed_snippet, false, shape, context.config)
-    } else {
-        Some(String::new())
-    }
-}
-
-/// Recover the missing comments in the specified span, if available.
-/// The layout of the comments will be preserved as long as it does not break the code
-/// and its total width does not exceed the max width.
-pub fn recover_missing_comment_in_span(
-    span: Span,
-    shape: Shape,
-    context: &RewriteContext,
-    used_width: usize,
-) -> Option<String> {
-    let missing_comment = rewrite_missing_comment(span, shape, context)?;
-    if missing_comment.is_empty() {
-        Some(String::new())
-    } else {
-        let missing_snippet = context.snippet(span);
-        let pos = missing_snippet.chars().position(|c| c == '/').unwrap_or(0);
-        // 1 = ` `
-        let total_width = missing_comment.len() + used_width + 1;
-        let force_new_line_before_comment =
-            missing_snippet[..pos].contains('\n') || total_width > context.config.max_width();
-        let sep = if force_new_line_before_comment {
-            format!("\n{}", shape.indent.to_string(context.config))
-        } else {
-            String::from(" ")
-        };
-        Some(format!("{}{}", sep, missing_comment))
-    }
-}
-
-/// Trims whitespace and aligns to indent, but otherwise does not change comments.
-fn light_rewrite_comment(orig: &str, offset: Indent, config: &Config) -> Option<String> {
-    let lines: Vec<&str> = orig.lines()
-        .map(|l| {
-            // This is basically just l.trim(), but in the case that a line starts
-            // with `*` we want to leave one space before it, so it aligns with the
-            // `*` in `/*`.
-            let first_non_whitespace = l.find(|c| !char::is_whitespace(c));
-            if let Some(fnw) = first_non_whitespace {
-                if l.as_bytes()[fnw] == b'*' && fnw > 0 {
-                    &l[fnw - 1..]
-                } else {
-                    &l[fnw..]
-                }
-            } else {
-                ""
-            }.trim_right()
-        })
-        .collect();
-    Some(lines.join(&format!("\n{}", offset.to_string(config))))
-}
-
-/// Trims comment characters and possibly a single space from the left of a string.
-/// Does not trim all whitespace. If a single space is trimmed from the left of the string,
-/// this function returns true.
-fn left_trim_comment_line<'a>(line: &'a str, style: &CommentStyle) -> (&'a str, bool) {
-    if line.starts_with("//! ") || line.starts_with("/// ") || line.starts_with("/*! ")
-        || line.starts_with("/** ")
-    {
-        (&line[4..], true)
-    } else if let CommentStyle::Custom(opener) = *style {
-        if line.starts_with(opener) {
-            (&line[opener.len()..], true)
-        } else {
-            (&line[opener.trim_right().len()..], false)
-        }
-    } else if line.starts_with("/* ") || line.starts_with("// ") || line.starts_with("//!")
-        || line.starts_with("///") || line.starts_with("** ")
-        || line.starts_with("/*!")
-        || (line.starts_with("/**") && !line.starts_with("/**/"))
-    {
-        (&line[3..], line.chars().nth(2).unwrap() == ' ')
-    } else if line.starts_with("/*") || line.starts_with("* ") || line.starts_with("//")
-        || line.starts_with("**")
-    {
-        (&line[2..], line.chars().nth(1).unwrap() == ' ')
-    } else if line.starts_with('*') {
-        (&line[1..], false)
-    } else {
-        (line, line.starts_with(' '))
-    }
-}
-
-pub trait FindUncommented {
-    fn find_uncommented(&self, pat: &str) -> Option<usize>;
-}
-
-impl FindUncommented for str {
-    fn find_uncommented(&self, pat: &str) -> Option<usize> {
-        let mut needle_iter = pat.chars();
-        for (kind, (i, b)) in CharClasses::new(self.char_indices()) {
-            match needle_iter.next() {
-                None => {
-                    return Some(i - pat.len());
-                }
-                Some(c) => match kind {
-                    FullCodeCharKind::Normal | FullCodeCharKind::InString if b == c => {}
-                    _ => {
-                        needle_iter = pat.chars();
-                    }
-                },
-            }
-        }
-
-        // Handle case where the pattern is a suffix of the search string
-        match needle_iter.next() {
-            Some(_) => None,
-            None => Some(self.len() - pat.len()),
-        }
-    }
-}
-
-// Returns the first byte position after the first comment. The given string
-// is expected to be prefixed by a comment, including delimiters.
-// Good: "/* /* inner */ outer */ code();"
-// Bad:  "code(); // hello\n world!"
-pub fn find_comment_end(s: &str) -> Option<usize> {
-    let mut iter = CharClasses::new(s.char_indices());
-    for (kind, (i, _c)) in &mut iter {
-        if kind == FullCodeCharKind::Normal || kind == FullCodeCharKind::InString {
-            return Some(i);
-        }
-    }
-
-    // Handle case where the comment ends at the end of s.
-    if iter.status == CharClassesStatus::Normal {
-        Some(s.len())
-    } else {
-        None
-    }
-}
-
-/// Returns true if text contains any comment.
-pub fn contains_comment(text: &str) -> bool {
-    CharClasses::new(text.chars()).any(|(kind, _)| kind.is_comment())
-}
-
-/// Remove trailing spaces from the specified snippet. We do not remove spaces
-/// inside strings or comments.
-pub fn remove_trailing_white_spaces(text: &str) -> String {
-    let mut buffer = String::with_capacity(text.len());
-    let mut space_buffer = String::with_capacity(128);
-    for (char_kind, c) in CharClasses::new(text.chars()) {
-        match c {
-            '\n' => {
-                if char_kind == FullCodeCharKind::InString {
-                    buffer.push_str(&space_buffer);
-                }
-                space_buffer.clear();
-                buffer.push('\n');
-            }
-            _ if c.is_whitespace() => {
-                space_buffer.push(c);
-            }
-            _ => {
-                if !space_buffer.is_empty() {
-                    buffer.push_str(&space_buffer);
-                    space_buffer.clear();
-                }
-                buffer.push(c);
-            }
-        }
-    }
-    buffer
-}
-
-pub struct CharClasses<T>
-where
-    T: Iterator,
-    T::Item: RichChar,
-{
-    base: iter::Peekable<T>,
-    status: CharClassesStatus,
-}
-
-pub trait RichChar {
-    fn get_char(&self) -> char;
-}
-
-impl RichChar for char {
-    fn get_char(&self) -> char {
-        *self
-    }
-}
-
-impl RichChar for (usize, char) {
-    fn get_char(&self) -> char {
-        self.1
-    }
-}
-
-impl RichChar for (char, usize) {
-    fn get_char(&self) -> char {
-        self.0
-    }
-}
-
-#[derive(PartialEq, Eq, Debug, Clone, Copy)]
-enum CharClassesStatus {
-    Normal,
-    LitString,
-    LitStringEscape,
-    LitChar,
-    LitCharEscape,
-    // The u32 is the nesting deepness of the comment
-    BlockComment(u32),
-    // Status when the '/' has been consumed, but not yet the '*', deepness is
-    // the new deepness (after the comment opening).
-    BlockCommentOpening(u32),
-    // Status when the '*' has been consumed, but not yet the '/', deepness is
-    // the new deepness (after the comment closing).
-    BlockCommentClosing(u32),
-    LineComment,
-}
-
-/// Distinguish between functional part of code and comments
-#[derive(PartialEq, Eq, Debug, Clone, Copy)]
-pub enum CodeCharKind {
-    Normal,
-    Comment,
-}
-
-/// Distinguish between functional part of code and comments,
-/// describing opening and closing of comments for ease when chunking
-/// code from tagged characters
-#[derive(PartialEq, Eq, Debug, Clone, Copy)]
-pub enum FullCodeCharKind {
-    Normal,
-    /// The first character of a comment, there is only one for a comment (always '/')
-    StartComment,
-    /// Any character inside a comment including the second character of comment
-    /// marks ("//", "/*")
-    InComment,
-    /// Last character of a comment, '\n' for a line comment, '/' for a block comment.
-    EndComment,
-    /// Inside a string.
-    InString,
-}
-
-impl FullCodeCharKind {
-    pub fn is_comment(&self) -> bool {
-        match *self {
-            FullCodeCharKind::StartComment
-            | FullCodeCharKind::InComment
-            | FullCodeCharKind::EndComment => true,
-            _ => false,
-        }
-    }
-
-    pub fn is_string(&self) -> bool {
-        *self == FullCodeCharKind::InString
-    }
-
-    fn to_codecharkind(&self) -> CodeCharKind {
-        if self.is_comment() {
-            CodeCharKind::Comment
-        } else {
-            CodeCharKind::Normal
-        }
-    }
-}
-
-impl<T> CharClasses<T>
-where
-    T: Iterator,
-    T::Item: RichChar,
-{
-    pub fn new(base: T) -> CharClasses<T> {
-        CharClasses {
-            base: base.peekable(),
-            status: CharClassesStatus::Normal,
-        }
-    }
-}
-
-impl<T> Iterator for CharClasses<T>
-where
-    T: Iterator,
-    T::Item: RichChar,
-{
-    type Item = (FullCodeCharKind, T::Item);
-
-    fn next(&mut self) -> Option<(FullCodeCharKind, T::Item)> {
-        let item = self.base.next()?;
-        let chr = item.get_char();
-        let mut char_kind = FullCodeCharKind::Normal;
-        self.status = match self.status {
-            CharClassesStatus::LitString => match chr {
-                '"' => CharClassesStatus::Normal,
-                '\\' => {
-                    char_kind = FullCodeCharKind::InString;
-                    CharClassesStatus::LitStringEscape
-                }
-                _ => {
-                    char_kind = FullCodeCharKind::InString;
-                    CharClassesStatus::LitString
-                }
-            },
-            CharClassesStatus::LitStringEscape => {
-                char_kind = FullCodeCharKind::InString;
-                CharClassesStatus::LitString
-            }
-            CharClassesStatus::LitChar => match chr {
-                '\\' => CharClassesStatus::LitCharEscape,
-                '\'' => CharClassesStatus::Normal,
-                _ => CharClassesStatus::LitChar,
-            },
-            CharClassesStatus::LitCharEscape => CharClassesStatus::LitChar,
-            CharClassesStatus::Normal => match chr {
-                '"' => {
-                    char_kind = FullCodeCharKind::InString;
-                    CharClassesStatus::LitString
-                }
-                '\'' => CharClassesStatus::LitChar,
-                '/' => match self.base.peek() {
-                    Some(next) if next.get_char() == '*' => {
-                        self.status = CharClassesStatus::BlockCommentOpening(1);
-                        return Some((FullCodeCharKind::StartComment, item));
-                    }
-                    Some(next) if next.get_char() == '/' => {
-                        self.status = CharClassesStatus::LineComment;
-                        return Some((FullCodeCharKind::StartComment, item));
-                    }
-                    _ => CharClassesStatus::Normal,
-                },
-                _ => CharClassesStatus::Normal,
-            },
-            CharClassesStatus::BlockComment(deepness) => {
-                assert_ne!(deepness, 0);
-                self.status = match self.base.peek() {
-                    Some(next) if next.get_char() == '/' && chr == '*' => {
-                        CharClassesStatus::BlockCommentClosing(deepness - 1)
-                    }
-                    Some(next) if next.get_char() == '*' && chr == '/' => {
-                        CharClassesStatus::BlockCommentOpening(deepness + 1)
-                    }
-                    _ => CharClassesStatus::BlockComment(deepness),
-                };
-                return Some((FullCodeCharKind::InComment, item));
-            }
-            CharClassesStatus::BlockCommentOpening(deepness) => {
-                assert_eq!(chr, '*');
-                self.status = CharClassesStatus::BlockComment(deepness);
-                return Some((FullCodeCharKind::InComment, item));
-            }
-            CharClassesStatus::BlockCommentClosing(deepness) => {
-                assert_eq!(chr, '/');
-                if deepness == 0 {
-                    self.status = CharClassesStatus::Normal;
-                    return Some((FullCodeCharKind::EndComment, item));
-                } else {
-                    self.status = CharClassesStatus::BlockComment(deepness);
-                    return Some((FullCodeCharKind::InComment, item));
-                }
-            }
-            CharClassesStatus::LineComment => match chr {
-                '\n' => {
-                    self.status = CharClassesStatus::Normal;
-                    return Some((FullCodeCharKind::EndComment, item));
-                }
-                _ => {
-                    self.status = CharClassesStatus::LineComment;
-                    return Some((FullCodeCharKind::InComment, item));
-                }
-            },
-        };
-        Some((char_kind, item))
-    }
-}
-
-/// Iterator over functional and commented parts of a string. Any part of a string is either
-/// functional code, either *one* block comment, either *one* line comment. Whitespace between
-/// comments is functional code. Line comments contain their ending newlines.
-struct UngroupedCommentCodeSlices<'a> {
-    slice: &'a str,
-    iter: iter::Peekable<CharClasses<std::str::CharIndices<'a>>>,
-}
-
-impl<'a> UngroupedCommentCodeSlices<'a> {
-    fn new(code: &'a str) -> UngroupedCommentCodeSlices<'a> {
-        UngroupedCommentCodeSlices {
-            slice: code,
-            iter: CharClasses::new(code.char_indices()).peekable(),
-        }
-    }
-}
-
-impl<'a> Iterator for UngroupedCommentCodeSlices<'a> {
-    type Item = (CodeCharKind, usize, &'a str);
-
-    fn next(&mut self) -> Option<Self::Item> {
-        let (kind, (start_idx, _)) = self.iter.next()?;
-        match kind {
-            FullCodeCharKind::Normal | FullCodeCharKind::InString => {
-                // Consume all the Normal code
-                while let Some(&(char_kind, _)) = self.iter.peek() {
-                    if char_kind.is_comment() {
-                        break;
-                    }
-                    let _ = self.iter.next();
-                }
-            }
-            FullCodeCharKind::StartComment => {
-                // Consume the whole comment
-                while let Some((FullCodeCharKind::InComment, (_, _))) = self.iter.next() {}
-            }
-            _ => panic!(),
-        }
-        let slice = match self.iter.peek() {
-            Some(&(_, (end_idx, _))) => &self.slice[start_idx..end_idx],
-            None => &self.slice[start_idx..],
-        };
-        Some((
-            if kind.is_comment() {
-                CodeCharKind::Comment
-            } else {
-                CodeCharKind::Normal
-            },
-            start_idx,
-            slice,
-        ))
-    }
-}
-
-/// Iterator over an alternating sequence of functional and commented parts of
-/// a string. The first item is always a, possibly zero length, subslice of
-/// functional text. Line style comments contain their ending newlines.
-pub struct CommentCodeSlices<'a> {
-    slice: &'a str,
-    last_slice_kind: CodeCharKind,
-    last_slice_end: usize,
-}
-
-impl<'a> CommentCodeSlices<'a> {
-    pub fn new(slice: &'a str) -> CommentCodeSlices<'a> {
-        CommentCodeSlices {
-            slice,
-            last_slice_kind: CodeCharKind::Comment,
-            last_slice_end: 0,
-        }
-    }
-}
-
-impl<'a> Iterator for CommentCodeSlices<'a> {
-    type Item = (CodeCharKind, usize, &'a str);
-
-    fn next(&mut self) -> Option<Self::Item> {
-        if self.last_slice_end == self.slice.len() {
-            return None;
-        }
-
-        let mut sub_slice_end = self.last_slice_end;
-        let mut first_whitespace = None;
-        let subslice = &self.slice[self.last_slice_end..];
-        let mut iter = CharClasses::new(subslice.char_indices());
-
-        for (kind, (i, c)) in &mut iter {
-            let is_comment_connector = self.last_slice_kind == CodeCharKind::Normal
-                && &subslice[..2] == "//"
-                && [' ', '\t'].contains(&c);
-
-            if is_comment_connector && first_whitespace.is_none() {
-                first_whitespace = Some(i);
-            }
-
-            if kind.to_codecharkind() == self.last_slice_kind && !is_comment_connector {
-                let last_index = match first_whitespace {
-                    Some(j) => j,
-                    None => i,
-                };
-                sub_slice_end = self.last_slice_end + last_index;
-                break;
-            }
-
-            if !is_comment_connector {
-                first_whitespace = None;
-            }
-        }
-
-        if let (None, true) = (iter.next(), sub_slice_end == self.last_slice_end) {
-            // This was the last subslice.
-            sub_slice_end = match first_whitespace {
-                Some(i) => self.last_slice_end + i,
-                None => self.slice.len(),
-            };
-        }
-
-        let kind = match self.last_slice_kind {
-            CodeCharKind::Comment => CodeCharKind::Normal,
-            CodeCharKind::Normal => CodeCharKind::Comment,
-        };
-        let res = (
-            kind,
-            self.last_slice_end,
-            &self.slice[self.last_slice_end..sub_slice_end],
-        );
-        self.last_slice_end = sub_slice_end;
-        self.last_slice_kind = kind;
-
-        Some(res)
-    }
-}
-
-/// Checks is `new` didn't miss any comment from `span`, if it removed any, return previous text
-/// (if it fits in the width/offset, else return None), else return `new`
-pub fn recover_comment_removed(
-    new: String,
-    span: Span,
-    context: &RewriteContext,
-) -> Option<String> {
-    let snippet = context.snippet(span);
-    if snippet != new && changed_comment_content(snippet, &new) {
-        // We missed some comments. Keep the original text.
-        Some(snippet.to_owned())
-    } else {
-        Some(new)
-    }
-}
-
-/// Return true if the two strings of code have the same payload of comments.
-/// The payload of comments is everything in the string except:
-///     - actual code (not comments)
-///     - comment start/end marks
-///     - whitespace
-///     - '*' at the beginning of lines in block comments
-fn changed_comment_content(orig: &str, new: &str) -> bool {
-    // Cannot write this as a fn since we cannot return types containing closures
-    let code_comment_content = |code| {
-        let slices = UngroupedCommentCodeSlices::new(code);
-        slices
-            .filter(|&(ref kind, _, _)| *kind == CodeCharKind::Comment)
-            .flat_map(|(_, _, s)| CommentReducer::new(s))
-    };
-    let res = code_comment_content(orig).ne(code_comment_content(new));
-    debug!(
-        "comment::changed_comment_content: {}\norig: '{}'\nnew: '{}'\nraw_old: {}\nraw_new: {}",
-        res,
-        orig,
-        new,
-        code_comment_content(orig).collect::<String>(),
-        code_comment_content(new).collect::<String>()
-    );
-    res
-}
-
-/// Iterator over the 'payload' characters of a comment.
-/// It skips whitespace, comment start/end marks, and '*' at the beginning of lines.
-/// The comment must be one comment, ie not more than one start mark (no multiple line comments,
-/// for example).
-struct CommentReducer<'a> {
-    is_block: bool,
-    at_start_line: bool,
-    iter: std::str::Chars<'a>,
-}
-
-impl<'a> CommentReducer<'a> {
-    fn new(comment: &'a str) -> CommentReducer<'a> {
-        let is_block = comment.starts_with("/*");
-        let comment = remove_comment_header(comment);
-        CommentReducer {
-            is_block,
-            at_start_line: false, // There are no supplementary '*' on the first line
-            iter: comment.chars(),
-        }
-    }
-}
-
-impl<'a> Iterator for CommentReducer<'a> {
-    type Item = char;
-    fn next(&mut self) -> Option<Self::Item> {
-        loop {
-            let mut c = self.iter.next()?;
-            if self.is_block && self.at_start_line {
-                while c.is_whitespace() {
-                    c = self.iter.next()?;
-                }
-                // Ignore leading '*'
-                if c == '*' {
-                    c = self.iter.next()?;
-                }
-            } else if c == '\n' {
-                self.at_start_line = true;
-            }
-            if !c.is_whitespace() {
-                return Some(c);
-            }
-        }
-    }
-}
-
-fn remove_comment_header(comment: &str) -> &str {
-    if comment.starts_with("///") || comment.starts_with("//!") {
-        &comment[3..]
-    } else if comment.starts_with("//") {
-        &comment[2..]
-    } else if (comment.starts_with("/**") && !comment.starts_with("/**/"))
-        || comment.starts_with("/*!")
-    {
-        &comment[3..comment.len() - 2]
-    } else {
-        assert!(
-            comment.starts_with("/*"),
-            format!("string '{}' is not a comment", comment)
-        );
-        &comment[2..comment.len() - 2]
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use super::{contains_comment, rewrite_comment, CharClasses, CodeCharKind, CommentCodeSlices,
-                FindUncommented, FullCodeCharKind};
-    use shape::{Indent, Shape};
-
-    #[test]
-    fn char_classes() {
-        let mut iter = CharClasses::new("//\n\n".chars());
-
-        assert_eq!((FullCodeCharKind::StartComment, '/'), iter.next().unwrap());
-        assert_eq!((FullCodeCharKind::InComment, '/'), iter.next().unwrap());
-        assert_eq!((FullCodeCharKind::EndComment, '\n'), iter.next().unwrap());
-        assert_eq!((FullCodeCharKind::Normal, '\n'), iter.next().unwrap());
-        assert_eq!(None, iter.next());
-    }
-
-    #[test]
-    fn comment_code_slices() {
-        let input = "code(); /* test */ 1 + 1";
-        let mut iter = CommentCodeSlices::new(input);
-
-        assert_eq!((CodeCharKind::Normal, 0, "code(); "), iter.next().unwrap());
-        assert_eq!(
-            (CodeCharKind::Comment, 8, "/* test */"),
-            iter.next().unwrap()
-        );
-        assert_eq!((CodeCharKind::Normal, 18, " 1 + 1"), iter.next().unwrap());
-        assert_eq!(None, iter.next());
-    }
-
-    #[test]
-    fn comment_code_slices_two() {
-        let input = "// comment\n    test();";
-        let mut iter = CommentCodeSlices::new(input);
-
-        assert_eq!((CodeCharKind::Normal, 0, ""), iter.next().unwrap());
-        assert_eq!(
-            (CodeCharKind::Comment, 0, "// comment\n"),
-            iter.next().unwrap()
-        );
-        assert_eq!(
-            (CodeCharKind::Normal, 11, "    test();"),
-            iter.next().unwrap()
-        );
-        assert_eq!(None, iter.next());
-    }
-
-    #[test]
-    fn comment_code_slices_three() {
-        let input = "1 // comment\n    // comment2\n\n";
-        let mut iter = CommentCodeSlices::new(input);
-
-        assert_eq!((CodeCharKind::Normal, 0, "1 "), iter.next().unwrap());
-        assert_eq!(
-            (CodeCharKind::Comment, 2, "// comment\n    // comment2\n"),
-            iter.next().unwrap()
-        );
-        assert_eq!((CodeCharKind::Normal, 29, "\n"), iter.next().unwrap());
-        assert_eq!(None, iter.next());
-    }
-
-    #[test]
-    #[cfg_attr(rustfmt, rustfmt_skip)]
-    fn format_comments() {
-        let mut config: ::config::Config = Default::default();
-        config.set().wrap_comments(true);
-        config.set().normalize_comments(true);
-
-        let comment = rewrite_comment(" //test",
-                                      true,
-                                      Shape::legacy(100, Indent::new(0, 100)),
-                                      &config).unwrap();
-        assert_eq!("/* test */", comment);
-
-        let comment = rewrite_comment("// comment on a",
-                                      false,
-                                      Shape::legacy(10, Indent::empty()),
-                                      &config).unwrap();
-        assert_eq!("// comment\n// on a", comment);
-
-        let comment = rewrite_comment("//  A multi line comment\n             // between args.",
-                                      false,
-                                      Shape::legacy(60, Indent::new(0, 12)),
-                                      &config).unwrap();
-        assert_eq!("//  A multi line comment\n            // between args.", comment);
-
-        let input = "// comment";
-        let expected =
-            "/* comment */";
-        let comment = rewrite_comment(input,
-                                      true,
-                                      Shape::legacy(9, Indent::new(0, 69)),
-                                      &config).unwrap();
-        assert_eq!(expected, comment);
-
-        let comment = rewrite_comment("/*   trimmed    */",
-                                      true,
-                                      Shape::legacy(100, Indent::new(0, 100)),
-                                      &config).unwrap();
-        assert_eq!("/* trimmed */", comment);
-    }
-
-    // This is probably intended to be a non-test fn, but it is not used. I'm
-    // keeping it around unless it helps us test stuff.
-    fn uncommented(text: &str) -> String {
-        CharClasses::new(text.chars())
-            .filter_map(|(s, c)| match s {
-                FullCodeCharKind::Normal | FullCodeCharKind::InString => Some(c),
-                _ => None,
-            })
-            .collect()
-    }
-
-    #[test]
-    fn test_uncommented() {
-        assert_eq!(&uncommented("abc/*...*/"), "abc");
-        assert_eq!(
-            &uncommented("// .... /* \n../* /* *** / */ */a/* // */c\n"),
-            "..ac\n"
-        );
-        assert_eq!(&uncommented("abc \" /* */\" qsdf"), "abc \" /* */\" qsdf");
-    }
-
-    #[test]
-    fn test_contains_comment() {
-        assert_eq!(contains_comment("abc"), false);
-        assert_eq!(contains_comment("abc // qsdf"), true);
-        assert_eq!(contains_comment("abc /* kqsdf"), true);
-        assert_eq!(contains_comment("abc \" /* */\" qsdf"), false);
-    }
-
-    #[test]
-    fn test_find_uncommented() {
-        fn check(haystack: &str, needle: &str, expected: Option<usize>) {
-            assert_eq!(expected, haystack.find_uncommented(needle));
-        }
-
-        check("/*/ */test", "test", Some(6));
-        check("//test\ntest", "test", Some(7));
-        check("/* comment only */", "whatever", None);
-        check(
-            "/* comment */ some text /* more commentary */ result",
-            "result",
-            Some(46),
-        );
-        check("sup // sup", "p", Some(2));
-        check("sup", "x", None);
-        check(r#"π? /**/ π is nice!"#, r#"π is nice"#, Some(9));
-        check("/*sup yo? \n sup*/ sup", "p", Some(20));
-        check("hel/*lohello*/lo", "hello", None);
-        check("acb", "ab", None);
-        check(",/*A*/ ", ",", Some(0));
-        check("abc", "abc", Some(0));
-        check("/* abc */", "abc", None);
-        check("/**/abc/* */", "abc", Some(4));
-        check("\"/* abc */\"", "abc", Some(4));
-        check("\"/* abc", "abc", Some(4));
-    }
-}
diff --git a/src/expr.rs b/src/expr.rs
deleted file mode 100644
index fb873ee26d3..00000000000
--- a/src/expr.rs
+++ /dev/null
@@ -1,2930 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::borrow::Cow;
-use std::cmp::min;
-use std::iter::repeat;
-
-use syntax::{ast, ptr};
-use syntax::codemap::{BytePos, CodeMap, Span};
-
-use chains::rewrite_chain;
-use closures;
-use codemap::{LineRangeUtils, SpanUtils};
-use comment::{combine_strs_with_missing_comments, contains_comment, recover_comment_removed,
-              rewrite_comment, rewrite_missing_comment, FindUncommented};
-use config::{Config, ControlBraceStyle, IndentStyle};
-use lists::{definitive_tactic, itemize_list, shape_for_tactic, struct_lit_formatting,
-            struct_lit_shape, struct_lit_tactic, write_list, DefinitiveListTactic, ListFormatting,
-            ListItem, ListTactic, Separator, SeparatorPlace, SeparatorTactic};
-use macros::{rewrite_macro, MacroArg, MacroPosition};
-use patterns::{can_be_overflowed_pat, TuplePatField};
-use rewrite::{Rewrite, RewriteContext};
-use shape::{Indent, Shape};
-use spanned::Spanned;
-use string::{rewrite_string, StringFormat};
-use types::{can_be_overflowed_type, rewrite_path, PathContext};
-use utils::{colon_spaces, contains_skip, count_newlines, extra_offset, first_line_width,
-            inner_attributes, last_line_extendable, last_line_width, mk_sp, outer_attributes,
-            paren_overhead, ptr_vec_to_ref_vec, semicolon_for_stmt, trimmed_last_line_width,
-            wrap_str};
-use vertical::rewrite_with_alignment;
-use visitor::FmtVisitor;
-
-impl Rewrite for ast::Expr {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        format_expr(self, ExprType::SubExpression, context, shape)
-    }
-}
-
-#[derive(Copy, Clone, PartialEq)]
-pub enum ExprType {
-    Statement,
-    SubExpression,
-}
-
-pub fn format_expr(
-    expr: &ast::Expr,
-    expr_type: ExprType,
-    context: &RewriteContext,
-    shape: Shape,
-) -> Option<String> {
-    skip_out_of_file_lines_range!(context, expr.span);
-
-    if contains_skip(&*expr.attrs) {
-        return Some(context.snippet(expr.span()).to_owned());
-    }
-
-    let expr_rw = match expr.node {
-        ast::ExprKind::Array(ref expr_vec) => rewrite_array(
-            &ptr_vec_to_ref_vec(expr_vec),
-            mk_sp(context.codemap.span_after(expr.span, "["), expr.span.hi()),
-            context,
-            shape,
-            false,
-        ),
-        ast::ExprKind::Lit(ref l) => rewrite_literal(context, l, shape),
-        ast::ExprKind::Call(ref callee, ref args) => {
-            let inner_span = mk_sp(callee.span.hi(), expr.span.hi());
-            let callee_str = callee.rewrite(context, shape)?;
-            rewrite_call(context, &callee_str, args, inner_span, shape)
-        }
-        ast::ExprKind::Paren(ref subexpr) => rewrite_paren(context, subexpr, shape),
-        ast::ExprKind::Binary(ref op, ref lhs, ref rhs) => {
-            // FIXME: format comments between operands and operator
-            rewrite_pair(
-                &**lhs,
-                &**rhs,
-                PairParts::new("", &format!(" {} ", context.snippet(op.span)), ""),
-                context,
-                shape,
-                context.config.binop_separator(),
-            )
-        }
-        ast::ExprKind::Unary(ref op, ref subexpr) => rewrite_unary_op(context, op, subexpr, shape),
-        ast::ExprKind::Struct(ref path, ref fields, ref base) => rewrite_struct_lit(
-            context,
-            path,
-            fields,
-            base.as_ref().map(|e| &**e),
-            expr.span,
-            shape,
-        ),
-        ast::ExprKind::Tup(ref items) => {
-            rewrite_tuple(context, &ptr_vec_to_ref_vec(items), expr.span, shape)
-        }
-        ast::ExprKind::If(..)
-        | ast::ExprKind::IfLet(..)
-        | ast::ExprKind::ForLoop(..)
-        | ast::ExprKind::Loop(..)
-        | ast::ExprKind::While(..)
-        | ast::ExprKind::WhileLet(..) => to_control_flow(expr, expr_type)
-            .and_then(|control_flow| control_flow.rewrite(context, shape)),
-        ast::ExprKind::Block(ref block) => {
-            match expr_type {
-                ExprType::Statement => {
-                    if is_unsafe_block(block) {
-                        block.rewrite(context, shape)
-                    } else if let rw @ Some(_) = rewrite_empty_block(context, block, shape) {
-                        // Rewrite block without trying to put it in a single line.
-                        rw
-                    } else {
-                        let prefix = block_prefix(context, block, shape)?;
-                        rewrite_block_with_visitor(context, &prefix, block, shape, true)
-                    }
-                }
-                ExprType::SubExpression => block.rewrite(context, shape),
-            }
-        }
-        ast::ExprKind::Match(ref cond, ref arms) => {
-            rewrite_match(context, cond, arms, shape, expr.span, &expr.attrs)
-        }
-        ast::ExprKind::Path(ref qself, ref path) => {
-            rewrite_path(context, PathContext::Expr, qself.as_ref(), path, shape)
-        }
-        ast::ExprKind::Assign(ref lhs, ref rhs) => {
-            rewrite_assignment(context, lhs, rhs, None, shape)
-        }
-        ast::ExprKind::AssignOp(ref op, ref lhs, ref rhs) => {
-            rewrite_assignment(context, lhs, rhs, Some(op), shape)
-        }
-        ast::ExprKind::Continue(ref opt_label) => {
-            let id_str = match *opt_label {
-                Some(label) => format!(" {}", label.ident),
-                None => String::new(),
-            };
-            Some(format!("continue{}", id_str))
-        }
-        ast::ExprKind::Break(ref opt_label, ref opt_expr) => {
-            let id_str = match *opt_label {
-                Some(label) => format!(" {}", label.ident),
-                None => String::new(),
-            };
-
-            if let Some(ref expr) = *opt_expr {
-                rewrite_unary_prefix(context, &format!("break{} ", id_str), &**expr, shape)
-            } else {
-                Some(format!("break{}", id_str))
-            }
-        }
-        ast::ExprKind::Yield(ref opt_expr) => if let Some(ref expr) = *opt_expr {
-            rewrite_unary_prefix(context, "yield ", &**expr, shape)
-        } else {
-            Some("yield".to_string())
-        },
-        ast::ExprKind::Closure(capture, movability, ref fn_decl, ref body, _) => {
-            closures::rewrite_closure(
-                capture,
-                movability,
-                fn_decl,
-                body,
-                expr.span,
-                context,
-                shape,
-            )
-        }
-        ast::ExprKind::Try(..)
-        | ast::ExprKind::Field(..)
-        | ast::ExprKind::TupField(..)
-        | ast::ExprKind::MethodCall(..) => rewrite_chain(expr, context, shape),
-        ast::ExprKind::Mac(ref mac) => {
-            rewrite_macro(mac, None, context, shape, MacroPosition::Expression).or_else(|| {
-                wrap_str(
-                    context.snippet(expr.span).to_owned(),
-                    context.config.max_width(),
-                    shape,
-                )
-            })
-        }
-        ast::ExprKind::Ret(None) => Some("return".to_owned()),
-        ast::ExprKind::Ret(Some(ref expr)) => {
-            rewrite_unary_prefix(context, "return ", &**expr, shape)
-        }
-        ast::ExprKind::Box(ref expr) => rewrite_unary_prefix(context, "box ", &**expr, shape),
-        ast::ExprKind::AddrOf(mutability, ref expr) => {
-            rewrite_expr_addrof(context, mutability, expr, shape)
-        }
-        ast::ExprKind::Cast(ref expr, ref ty) => rewrite_pair(
-            &**expr,
-            &**ty,
-            PairParts::new("", " as ", ""),
-            context,
-            shape,
-            SeparatorPlace::Front,
-        ),
-        ast::ExprKind::Type(ref expr, ref ty) => rewrite_pair(
-            &**expr,
-            &**ty,
-            PairParts::new("", ": ", ""),
-            context,
-            shape,
-            SeparatorPlace::Back,
-        ),
-        ast::ExprKind::Index(ref expr, ref index) => {
-            rewrite_index(&**expr, &**index, context, shape)
-        }
-        ast::ExprKind::Repeat(ref expr, ref repeats) => {
-            let (lbr, rbr) = if context.config.spaces_within_parens_and_brackets() {
-                ("[ ", " ]")
-            } else {
-                ("[", "]")
-            };
-            rewrite_pair(
-                &**expr,
-                &**repeats,
-                PairParts::new(lbr, "; ", rbr),
-                context,
-                shape,
-                SeparatorPlace::Back,
-            )
-        }
-        ast::ExprKind::Range(ref lhs, ref rhs, limits) => {
-            let delim = match limits {
-                ast::RangeLimits::HalfOpen => "..",
-                ast::RangeLimits::Closed => "..=",
-            };
-
-            fn needs_space_before_range(context: &RewriteContext, lhs: &ast::Expr) -> bool {
-                match lhs.node {
-                    ast::ExprKind::Lit(ref lit) => match lit.node {
-                        ast::LitKind::FloatUnsuffixed(..) => {
-                            context.snippet(lit.span).ends_with('.')
-                        }
-                        _ => false,
-                    },
-                    _ => false,
-                }
-            }
-
-            match (lhs.as_ref().map(|x| &**x), rhs.as_ref().map(|x| &**x)) {
-                (Some(lhs), Some(rhs)) => {
-                    let sp_delim = if context.config.spaces_around_ranges() {
-                        format!(" {} ", delim)
-                    } else if needs_space_before_range(context, lhs) {
-                        format!(" {}", delim)
-                    } else {
-                        delim.to_owned()
-                    };
-                    rewrite_pair(
-                        &*lhs,
-                        &*rhs,
-                        PairParts::new("", &sp_delim, ""),
-                        context,
-                        shape,
-                        context.config.binop_separator(),
-                    )
-                }
-                (None, Some(rhs)) => {
-                    let sp_delim = if context.config.spaces_around_ranges() {
-                        format!("{} ", delim)
-                    } else {
-                        delim.to_owned()
-                    };
-                    rewrite_unary_prefix(context, &sp_delim, &*rhs, shape)
-                }
-                (Some(lhs), None) => {
-                    let sp_delim = if context.config.spaces_around_ranges() {
-                        format!(" {}", delim)
-                    } else {
-                        delim.to_owned()
-                    };
-                    rewrite_unary_suffix(context, &sp_delim, &*lhs, shape)
-                }
-                (None, None) => Some(delim.to_owned()),
-            }
-        }
-        // We do not format these expressions yet, but they should still
-        // satisfy our width restrictions.
-        ast::ExprKind::InPlace(..) | ast::ExprKind::InlineAsm(..) => {
-            Some(context.snippet(expr.span).to_owned())
-        }
-        ast::ExprKind::Catch(ref block) => {
-            if let rw @ Some(_) = rewrite_single_line_block(context, "do catch ", block, shape) {
-                rw
-            } else {
-                // 9 = `do catch `
-                let budget = shape.width.checked_sub(9).unwrap_or(0);
-                Some(format!(
-                    "{}{}",
-                    "do catch ",
-                    block.rewrite(context, Shape::legacy(budget, shape.indent))?
-                ))
-            }
-        }
-    };
-
-    expr_rw
-        .and_then(|expr_str| recover_comment_removed(expr_str, expr.span, context))
-        .and_then(|expr_str| {
-            let attrs = outer_attributes(&expr.attrs);
-            let attrs_str = attrs.rewrite(context, shape)?;
-            let span = mk_sp(
-                attrs.last().map_or(expr.span.lo(), |attr| attr.span.hi()),
-                expr.span.lo(),
-            );
-            combine_strs_with_missing_comments(context, &attrs_str, &expr_str, span, shape, false)
-        })
-}
-
-#[derive(new, Clone, Copy)]
-pub struct PairParts<'a> {
-    prefix: &'a str,
-    infix: &'a str,
-    suffix: &'a str,
-}
-
-pub fn rewrite_pair<LHS, RHS>(
-    lhs: &LHS,
-    rhs: &RHS,
-    pp: PairParts,
-    context: &RewriteContext,
-    shape: Shape,
-    separator_place: SeparatorPlace,
-) -> Option<String>
-where
-    LHS: Rewrite,
-    RHS: Rewrite,
-{
-    let lhs_overhead = match separator_place {
-        SeparatorPlace::Back => shape.used_width() + pp.prefix.len() + pp.infix.trim_right().len(),
-        SeparatorPlace::Front => shape.used_width(),
-    };
-    let lhs_shape = Shape {
-        width: context.budget(lhs_overhead),
-        ..shape
-    };
-    let lhs_result = lhs.rewrite(context, lhs_shape)
-        .map(|lhs_str| format!("{}{}", pp.prefix, lhs_str))?;
-
-    // Try to the both lhs and rhs on the same line.
-    let rhs_orig_result = shape
-        .offset_left(last_line_width(&lhs_result) + pp.infix.len())
-        .and_then(|s| s.sub_width(pp.suffix.len()))
-        .and_then(|rhs_shape| rhs.rewrite(context, rhs_shape));
-    if let Some(ref rhs_result) = rhs_orig_result {
-        // If the rhs looks like block expression, we allow it to stay on the same line
-        // with the lhs even if it is multi-lined.
-        let allow_same_line = rhs_result
-            .lines()
-            .next()
-            .map(|first_line| first_line.ends_with('{'))
-            .unwrap_or(false);
-        if !rhs_result.contains('\n') || allow_same_line {
-            let one_line_width = last_line_width(&lhs_result) + pp.infix.len()
-                + first_line_width(rhs_result) + pp.suffix.len();
-            if one_line_width <= shape.width {
-                return Some(format!(
-                    "{}{}{}{}",
-                    lhs_result, pp.infix, rhs_result, pp.suffix
-                ));
-            }
-        }
-    }
-
-    // We have to use multiple lines.
-    // Re-evaluate the rhs because we have more space now:
-    let mut rhs_shape = match context.config.indent_style() {
-        IndentStyle::Visual => shape
-            .sub_width(pp.suffix.len() + pp.prefix.len())?
-            .visual_indent(pp.prefix.len()),
-        IndentStyle::Block => {
-            // Try to calculate the initial constraint on the right hand side.
-            let rhs_overhead = shape.rhs_overhead(context.config);
-            Shape::indented(shape.indent.block_indent(context.config), context.config)
-                .sub_width(rhs_overhead)?
-        }
-    };
-    let infix = match separator_place {
-        SeparatorPlace::Back => pp.infix.trim_right(),
-        SeparatorPlace::Front => pp.infix.trim_left(),
-    };
-    if separator_place == SeparatorPlace::Front {
-        rhs_shape = rhs_shape.offset_left(infix.len())?;
-    }
-    let rhs_result = rhs.rewrite(context, rhs_shape)?;
-    let indent_str = rhs_shape.indent.to_string(context.config);
-    let infix_with_sep = match separator_place {
-        SeparatorPlace::Back => format!("{}\n{}", infix, indent_str),
-        SeparatorPlace::Front => format!("\n{}{}", indent_str, infix),
-    };
-    Some(format!(
-        "{}{}{}{}",
-        lhs_result, infix_with_sep, rhs_result, pp.suffix
-    ))
-}
-
-pub fn rewrite_array<T: Rewrite + Spanned + ToExpr>(
-    exprs: &[&T],
-    span: Span,
-    context: &RewriteContext,
-    shape: Shape,
-    trailing_comma: bool,
-) -> Option<String> {
-    let bracket_size = if context.config.spaces_within_parens_and_brackets() {
-        2 // "[ "
-    } else {
-        1 // "["
-    };
-
-    let nested_shape = match context.config.indent_style() {
-        IndentStyle::Block => shape
-            .block()
-            .block_indent(context.config.tab_spaces())
-            .with_max_width(context.config)
-            .sub_width(1)?,
-        IndentStyle::Visual => shape
-            .visual_indent(bracket_size)
-            .sub_width(bracket_size * 2)?,
-    };
-
-    let items = itemize_list(
-        context.codemap,
-        exprs.iter(),
-        "]",
-        ",",
-        |item| item.span().lo(),
-        |item| item.span().hi(),
-        |item| item.rewrite(context, nested_shape),
-        span.lo(),
-        span.hi(),
-        false,
-    ).collect::<Vec<_>>();
-
-    if items.is_empty() {
-        if context.config.spaces_within_parens_and_brackets() {
-            return Some("[ ]".to_string());
-        } else {
-            return Some("[]".to_string());
-        }
-    }
-
-    let tactic = array_tactic(context, shape, nested_shape, exprs, &items, bracket_size);
-    let ends_with_newline = tactic.ends_with_newline(context.config.indent_style());
-
-    let fmt = ListFormatting {
-        tactic,
-        separator: ",",
-        trailing_separator: if trailing_comma {
-            SeparatorTactic::Always
-        } else if context.inside_macro && !exprs.is_empty() {
-            let ends_with_bracket = context.snippet(span).ends_with(']');
-            let bracket_offset = if ends_with_bracket { 1 } else { 0 };
-            let snippet = context.snippet(mk_sp(span.lo(), span.hi() - BytePos(bracket_offset)));
-            let last_char_index = snippet.rfind(|c: char| !c.is_whitespace())?;
-            if &snippet[last_char_index..last_char_index + 1] == "," {
-                SeparatorTactic::Always
-            } else {
-                SeparatorTactic::Never
-            }
-        } else if context.config.indent_style() == IndentStyle::Visual {
-            SeparatorTactic::Never
-        } else {
-            SeparatorTactic::Vertical
-        },
-        separator_place: SeparatorPlace::Back,
-        shape: nested_shape,
-        ends_with_newline,
-        preserve_newline: false,
-        config: context.config,
-    };
-    let list_str = write_list(&items, &fmt)?;
-
-    let result = if context.config.indent_style() == IndentStyle::Visual
-        || tactic == DefinitiveListTactic::Horizontal
-    {
-        if context.config.spaces_within_parens_and_brackets() && !list_str.is_empty() {
-            format!("[ {} ]", list_str)
-        } else {
-            format!("[{}]", list_str)
-        }
-    } else {
-        format!(
-            "[\n{}{}\n{}]",
-            nested_shape.indent.to_string(context.config),
-            list_str,
-            shape.block().indent.to_string(context.config)
-        )
-    };
-
-    Some(result)
-}
-
-fn array_tactic<T: Rewrite + Spanned + ToExpr>(
-    context: &RewriteContext,
-    shape: Shape,
-    nested_shape: Shape,
-    exprs: &[&T],
-    items: &[ListItem],
-    bracket_size: usize,
-) -> DefinitiveListTactic {
-    let has_long_item = items
-        .iter()
-        .any(|li| li.item.as_ref().map(|s| s.len() > 10).unwrap_or(false));
-
-    match context.config.indent_style() {
-        IndentStyle::Block => {
-            let tactic = match shape.width.checked_sub(2 * bracket_size) {
-                Some(width) => {
-                    let tactic = ListTactic::LimitedHorizontalVertical(
-                        context.config.width_heuristics().array_width,
-                    );
-                    definitive_tactic(items, tactic, Separator::Comma, width)
-                }
-                None => DefinitiveListTactic::Vertical,
-            };
-            if tactic == DefinitiveListTactic::Vertical && !has_long_item
-                && is_every_args_simple(exprs)
-            {
-                DefinitiveListTactic::Mixed
-            } else {
-                tactic
-            }
-        }
-        IndentStyle::Visual => {
-            if has_long_item || items.iter().any(ListItem::is_multiline) {
-                definitive_tactic(
-                    items,
-                    ListTactic::LimitedHorizontalVertical(
-                        context.config.width_heuristics().array_width,
-                    ),
-                    Separator::Comma,
-                    nested_shape.width,
-                )
-            } else {
-                DefinitiveListTactic::Mixed
-            }
-        }
-    }
-}
-
-fn nop_block_collapse(block_str: Option<String>, budget: usize) -> Option<String> {
-    debug!("nop_block_collapse {:?} {}", block_str, budget);
-    block_str.map(|block_str| {
-        if block_str.starts_with('{') && budget >= 2
-            && (block_str[1..].find(|c: char| !c.is_whitespace()).unwrap() == block_str.len() - 2)
-        {
-            "{}".to_owned()
-        } else {
-            block_str.to_owned()
-        }
-    })
-}
-
-fn rewrite_empty_block(
-    context: &RewriteContext,
-    block: &ast::Block,
-    shape: Shape,
-) -> Option<String> {
-    if block.stmts.is_empty() && !block_contains_comment(block, context.codemap) && shape.width >= 2
-    {
-        return Some("{}".to_owned());
-    }
-
-    // If a block contains only a single-line comment, then leave it on one line.
-    let user_str = context.snippet(block.span);
-    let user_str = user_str.trim();
-    if user_str.starts_with('{') && user_str.ends_with('}') {
-        let comment_str = user_str[1..user_str.len() - 1].trim();
-        if block.stmts.is_empty() && !comment_str.contains('\n') && !comment_str.starts_with("//")
-            && comment_str.len() + 4 <= shape.width
-        {
-            return Some(format!("{{ {} }}", comment_str));
-        }
-    }
-
-    None
-}
-
-fn block_prefix(context: &RewriteContext, block: &ast::Block, shape: Shape) -> Option<String> {
-    Some(match block.rules {
-        ast::BlockCheckMode::Unsafe(..) => {
-            let snippet = context.snippet(block.span);
-            let open_pos = snippet.find_uncommented("{")?;
-            // Extract comment between unsafe and block start.
-            let trimmed = &snippet[6..open_pos].trim();
-
-            if !trimmed.is_empty() {
-                // 9 = "unsafe  {".len(), 7 = "unsafe ".len()
-                let budget = shape.width.checked_sub(9)?;
-                format!(
-                    "unsafe {} ",
-                    rewrite_comment(
-                        trimmed,
-                        true,
-                        Shape::legacy(budget, shape.indent + 7),
-                        context.config,
-                    )?
-                )
-            } else {
-                "unsafe ".to_owned()
-            }
-        }
-        ast::BlockCheckMode::Default => String::new(),
-    })
-}
-
-fn rewrite_single_line_block(
-    context: &RewriteContext,
-    prefix: &str,
-    block: &ast::Block,
-    shape: Shape,
-) -> Option<String> {
-    if is_simple_block(block, context.codemap) {
-        let expr_shape = shape.offset_left(last_line_width(prefix))?;
-        let expr_str = block.stmts[0].rewrite(context, expr_shape)?;
-        let result = format!("{}{{ {} }}", prefix, expr_str);
-        if result.len() <= shape.width && !result.contains('\n') {
-            return Some(result);
-        }
-    }
-    None
-}
-
-pub fn rewrite_block_with_visitor(
-    context: &RewriteContext,
-    prefix: &str,
-    block: &ast::Block,
-    shape: Shape,
-    has_braces: bool,
-) -> Option<String> {
-    if let rw @ Some(_) = rewrite_empty_block(context, block, shape) {
-        return rw;
-    }
-
-    let mut visitor = FmtVisitor::from_context(context);
-    visitor.block_indent = shape.indent;
-    visitor.is_if_else_block = context.is_if_else_block;
-    match block.rules {
-        ast::BlockCheckMode::Unsafe(..) => {
-            let snippet = context.snippet(block.span);
-            let open_pos = snippet.find_uncommented("{")?;
-            visitor.last_pos = block.span.lo() + BytePos(open_pos as u32)
-        }
-        ast::BlockCheckMode::Default => visitor.last_pos = block.span.lo(),
-    }
-
-    visitor.visit_block(block, None, has_braces);
-    Some(format!("{}{}", prefix, visitor.buffer))
-}
-
-impl Rewrite for ast::Block {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        // shape.width is used only for the single line case: either the empty block `{}`,
-        // or an unsafe expression `unsafe { e }`.
-        if let rw @ Some(_) = rewrite_empty_block(context, self, shape) {
-            return rw;
-        }
-
-        let prefix = block_prefix(context, self, shape)?;
-
-        let result = rewrite_block_with_visitor(context, &prefix, self, shape, true);
-        if let Some(ref result_str) = result {
-            if result_str.lines().count() <= 3 {
-                if let rw @ Some(_) = rewrite_single_line_block(context, &prefix, self, shape) {
-                    return rw;
-                }
-            }
-        }
-
-        result
-    }
-}
-
-impl Rewrite for ast::Stmt {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        skip_out_of_file_lines_range!(context, self.span());
-
-        let result = match self.node {
-            ast::StmtKind::Local(ref local) => local.rewrite(context, shape),
-            ast::StmtKind::Expr(ref ex) | ast::StmtKind::Semi(ref ex) => {
-                let suffix = if semicolon_for_stmt(context, self) {
-                    ";"
-                } else {
-                    ""
-                };
-
-                let shape = shape.sub_width(suffix.len())?;
-                format_expr(ex, ExprType::Statement, context, shape).map(|s| s + suffix)
-            }
-            ast::StmtKind::Mac(..) | ast::StmtKind::Item(..) => None,
-        };
-        result.and_then(|res| recover_comment_removed(res, self.span(), context))
-    }
-}
-
-// Rewrite condition if the given expression has one.
-pub fn rewrite_cond(context: &RewriteContext, expr: &ast::Expr, shape: Shape) -> Option<String> {
-    match expr.node {
-        ast::ExprKind::Match(ref cond, _) => {
-            // `match `cond` {`
-            let cond_shape = match context.config.indent_style() {
-                IndentStyle::Visual => shape.shrink_left(6).and_then(|s| s.sub_width(2))?,
-                IndentStyle::Block => shape.offset_left(8)?,
-            };
-            cond.rewrite(context, cond_shape)
-        }
-        _ => to_control_flow(expr, ExprType::SubExpression).and_then(|control_flow| {
-            let alt_block_sep =
-                String::from("\n") + &shape.indent.block_only().to_string(context.config);
-            control_flow
-                .rewrite_cond(context, shape, &alt_block_sep)
-                .and_then(|rw| Some(rw.0))
-        }),
-    }
-}
-
-// Abstraction over control flow expressions
-#[derive(Debug)]
-struct ControlFlow<'a> {
-    cond: Option<&'a ast::Expr>,
-    block: &'a ast::Block,
-    else_block: Option<&'a ast::Expr>,
-    label: Option<ast::Label>,
-    pat: Option<&'a ast::Pat>,
-    keyword: &'a str,
-    matcher: &'a str,
-    connector: &'a str,
-    allow_single_line: bool,
-    // True if this is an `if` expression in an `else if` :-( hacky
-    nested_if: bool,
-    span: Span,
-}
-
-fn to_control_flow(expr: &ast::Expr, expr_type: ExprType) -> Option<ControlFlow> {
-    match expr.node {
-        ast::ExprKind::If(ref cond, ref if_block, ref else_block) => Some(ControlFlow::new_if(
-            cond,
-            None,
-            if_block,
-            else_block.as_ref().map(|e| &**e),
-            expr_type == ExprType::SubExpression,
-            false,
-            expr.span,
-        )),
-        ast::ExprKind::IfLet(ref pat, ref cond, ref if_block, ref else_block) => {
-            Some(ControlFlow::new_if(
-                cond,
-                Some(pat),
-                if_block,
-                else_block.as_ref().map(|e| &**e),
-                expr_type == ExprType::SubExpression,
-                false,
-                expr.span,
-            ))
-        }
-        ast::ExprKind::ForLoop(ref pat, ref cond, ref block, label) => {
-            Some(ControlFlow::new_for(pat, cond, block, label, expr.span))
-        }
-        ast::ExprKind::Loop(ref block, label) => {
-            Some(ControlFlow::new_loop(block, label, expr.span))
-        }
-        ast::ExprKind::While(ref cond, ref block, label) => {
-            Some(ControlFlow::new_while(None, cond, block, label, expr.span))
-        }
-        ast::ExprKind::WhileLet(ref pat, ref cond, ref block, label) => Some(
-            ControlFlow::new_while(Some(pat), cond, block, label, expr.span),
-        ),
-        _ => None,
-    }
-}
-
-impl<'a> ControlFlow<'a> {
-    fn new_if(
-        cond: &'a ast::Expr,
-        pat: Option<&'a ast::Pat>,
-        block: &'a ast::Block,
-        else_block: Option<&'a ast::Expr>,
-        allow_single_line: bool,
-        nested_if: bool,
-        span: Span,
-    ) -> ControlFlow<'a> {
-        ControlFlow {
-            cond: Some(cond),
-            block,
-            else_block,
-            label: None,
-            pat,
-            keyword: "if",
-            matcher: match pat {
-                Some(..) => "let",
-                None => "",
-            },
-            connector: " =",
-            allow_single_line,
-            nested_if,
-            span,
-        }
-    }
-
-    fn new_loop(block: &'a ast::Block, label: Option<ast::Label>, span: Span) -> ControlFlow<'a> {
-        ControlFlow {
-            cond: None,
-            block,
-            else_block: None,
-            label,
-            pat: None,
-            keyword: "loop",
-            matcher: "",
-            connector: "",
-            allow_single_line: false,
-            nested_if: false,
-            span,
-        }
-    }
-
-    fn new_while(
-        pat: Option<&'a ast::Pat>,
-        cond: &'a ast::Expr,
-        block: &'a ast::Block,
-        label: Option<ast::Label>,
-        span: Span,
-    ) -> ControlFlow<'a> {
-        ControlFlow {
-            cond: Some(cond),
-            block,
-            else_block: None,
-            label,
-            pat,
-            keyword: "while",
-            matcher: match pat {
-                Some(..) => "let",
-                None => "",
-            },
-            connector: " =",
-            allow_single_line: false,
-            nested_if: false,
-            span,
-        }
-    }
-
-    fn new_for(
-        pat: &'a ast::Pat,
-        cond: &'a ast::Expr,
-        block: &'a ast::Block,
-        label: Option<ast::Label>,
-        span: Span,
-    ) -> ControlFlow<'a> {
-        ControlFlow {
-            cond: Some(cond),
-            block,
-            else_block: None,
-            label,
-            pat: Some(pat),
-            keyword: "for",
-            matcher: "",
-            connector: " in",
-            allow_single_line: false,
-            nested_if: false,
-            span,
-        }
-    }
-
-    fn rewrite_single_line(
-        &self,
-        pat_expr_str: &str,
-        context: &RewriteContext,
-        width: usize,
-    ) -> Option<String> {
-        assert!(self.allow_single_line);
-        let else_block = self.else_block?;
-        let fixed_cost = self.keyword.len() + "  {  } else {  }".len();
-
-        if let ast::ExprKind::Block(ref else_node) = else_block.node {
-            if !is_simple_block(self.block, context.codemap)
-                || !is_simple_block(else_node, context.codemap)
-                || pat_expr_str.contains('\n')
-            {
-                return None;
-            }
-
-            let new_width = width.checked_sub(pat_expr_str.len() + fixed_cost)?;
-            let expr = &self.block.stmts[0];
-            let if_str = expr.rewrite(context, Shape::legacy(new_width, Indent::empty()))?;
-
-            let new_width = new_width.checked_sub(if_str.len())?;
-            let else_expr = &else_node.stmts[0];
-            let else_str = else_expr.rewrite(context, Shape::legacy(new_width, Indent::empty()))?;
-
-            if if_str.contains('\n') || else_str.contains('\n') {
-                return None;
-            }
-
-            let result = format!(
-                "{} {} {{ {} }} else {{ {} }}",
-                self.keyword, pat_expr_str, if_str, else_str
-            );
-
-            if result.len() <= width {
-                return Some(result);
-            }
-        }
-
-        None
-    }
-}
-
-impl<'a> ControlFlow<'a> {
-    fn rewrite_cond(
-        &self,
-        context: &RewriteContext,
-        shape: Shape,
-        alt_block_sep: &str,
-    ) -> Option<(String, usize)> {
-        // Do not take the rhs overhead from the upper expressions into account
-        // when rewriting pattern.
-        let new_width = context
-            .config
-            .max_width()
-            .checked_sub(shape.used_width())
-            .unwrap_or(0);
-        let fresh_shape = Shape {
-            width: new_width,
-            ..shape
-        };
-        let constr_shape = if self.nested_if {
-            // We are part of an if-elseif-else chain. Our constraints are tightened.
-            // 7 = "} else " .len()
-            fresh_shape.offset_left(7)?
-        } else {
-            fresh_shape
-        };
-
-        let label_string = rewrite_label(self.label);
-        // 1 = space after keyword.
-        let offset = self.keyword.len() + label_string.len() + 1;
-
-        let pat_expr_string = match self.cond {
-            Some(cond) => rewrite_pat_expr(
-                context,
-                self.pat,
-                cond,
-                self.matcher,
-                self.connector,
-                self.keyword,
-                constr_shape,
-                offset,
-            )?,
-            None => String::new(),
-        };
-
-        let brace_overhead =
-            if context.config.control_brace_style() != ControlBraceStyle::AlwaysNextLine {
-                // 2 = ` {`
-                2
-            } else {
-                0
-            };
-        let one_line_budget = context
-            .config
-            .max_width()
-            .checked_sub(constr_shape.used_width() + offset + brace_overhead)
-            .unwrap_or(0);
-        let force_newline_brace = (pat_expr_string.contains('\n')
-            || pat_expr_string.len() > one_line_budget)
-            && !last_line_extendable(&pat_expr_string);
-
-        // Try to format if-else on single line.
-        if self.allow_single_line
-            && context
-                .config
-                .width_heuristics()
-                .single_line_if_else_max_width > 0
-        {
-            let trial = self.rewrite_single_line(&pat_expr_string, context, shape.width);
-
-            if let Some(cond_str) = trial {
-                if cond_str.len()
-                    <= context
-                        .config
-                        .width_heuristics()
-                        .single_line_if_else_max_width
-                {
-                    return Some((cond_str, 0));
-                }
-            }
-        }
-
-        let cond_span = if let Some(cond) = self.cond {
-            cond.span
-        } else {
-            mk_sp(self.block.span.lo(), self.block.span.lo())
-        };
-
-        // `for event in event`
-        // Do not include label in the span.
-        let lo = self.label.map_or(self.span.lo(), |label| label.span.hi());
-        let between_kwd_cond = mk_sp(
-            context
-                .codemap
-                .span_after(mk_sp(lo, self.span.hi()), self.keyword.trim()),
-            self.pat.map_or(cond_span.lo(), |p| {
-                if self.matcher.is_empty() {
-                    p.span.lo()
-                } else {
-                    context.codemap.span_before(self.span, self.matcher.trim())
-                }
-            }),
-        );
-
-        let between_kwd_cond_comment = extract_comment(between_kwd_cond, context, shape);
-
-        let after_cond_comment =
-            extract_comment(mk_sp(cond_span.hi(), self.block.span.lo()), context, shape);
-
-        let block_sep = if self.cond.is_none() && between_kwd_cond_comment.is_some() {
-            ""
-        } else if context.config.control_brace_style() == ControlBraceStyle::AlwaysNextLine
-            || force_newline_brace
-        {
-            alt_block_sep
-        } else {
-            " "
-        };
-
-        let used_width = if pat_expr_string.contains('\n') {
-            last_line_width(&pat_expr_string)
-        } else {
-            // 2 = spaces after keyword and condition.
-            label_string.len() + self.keyword.len() + pat_expr_string.len() + 2
-        };
-
-        Some((
-            format!(
-                "{}{}{}{}{}",
-                label_string,
-                self.keyword,
-                between_kwd_cond_comment.as_ref().map_or(
-                    if pat_expr_string.is_empty() || pat_expr_string.starts_with('\n') {
-                        ""
-                    } else {
-                        " "
-                    },
-                    |s| &**s,
-                ),
-                pat_expr_string,
-                after_cond_comment.as_ref().map_or(block_sep, |s| &**s)
-            ),
-            used_width,
-        ))
-    }
-}
-
-impl<'a> Rewrite for ControlFlow<'a> {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        debug!("ControlFlow::rewrite {:?} {:?}", self, shape);
-
-        let alt_block_sep = String::from("\n") + &shape.indent.to_string(context.config);
-        let (cond_str, used_width) = self.rewrite_cond(context, shape, &alt_block_sep)?;
-        // If `used_width` is 0, it indicates that whole control flow is written in a single line.
-        if used_width == 0 {
-            return Some(cond_str);
-        }
-
-        let block_width = shape.width.checked_sub(used_width).unwrap_or(0);
-        // This is used only for the empty block case: `{}`. So, we use 1 if we know
-        // we should avoid the single line case.
-        let block_width = if self.else_block.is_some() || self.nested_if {
-            min(1, block_width)
-        } else {
-            block_width
-        };
-        let block_shape = Shape {
-            width: block_width,
-            ..shape
-        };
-        let mut block_context = context.clone();
-        block_context.is_if_else_block = self.else_block.is_some();
-        let block_str =
-            rewrite_block_with_visitor(&block_context, "", self.block, block_shape, true)?;
-
-        let mut result = format!("{}{}", cond_str, block_str);
-
-        if let Some(else_block) = self.else_block {
-            let shape = Shape::indented(shape.indent, context.config);
-            let mut last_in_chain = false;
-            let rewrite = match else_block.node {
-                // If the else expression is another if-else expression, prevent it
-                // from being formatted on a single line.
-                // Note how we're passing the original shape, as the
-                // cost of "else" should not cascade.
-                ast::ExprKind::IfLet(ref pat, ref cond, ref if_block, ref next_else_block) => {
-                    ControlFlow::new_if(
-                        cond,
-                        Some(pat),
-                        if_block,
-                        next_else_block.as_ref().map(|e| &**e),
-                        false,
-                        true,
-                        mk_sp(else_block.span.lo(), self.span.hi()),
-                    ).rewrite(context, shape)
-                }
-                ast::ExprKind::If(ref cond, ref if_block, ref next_else_block) => {
-                    ControlFlow::new_if(
-                        cond,
-                        None,
-                        if_block,
-                        next_else_block.as_ref().map(|e| &**e),
-                        false,
-                        true,
-                        mk_sp(else_block.span.lo(), self.span.hi()),
-                    ).rewrite(context, shape)
-                }
-                _ => {
-                    last_in_chain = true;
-                    // When rewriting a block, the width is only used for single line
-                    // blocks, passing 1 lets us avoid that.
-                    let else_shape = Shape {
-                        width: min(1, shape.width),
-                        ..shape
-                    };
-                    format_expr(else_block, ExprType::Statement, context, else_shape)
-                }
-            };
-
-            let between_kwd_else_block = mk_sp(
-                self.block.span.hi(),
-                context
-                    .codemap
-                    .span_before(mk_sp(self.block.span.hi(), else_block.span.lo()), "else"),
-            );
-            let between_kwd_else_block_comment =
-                extract_comment(between_kwd_else_block, context, shape);
-
-            let after_else = mk_sp(
-                context
-                    .codemap
-                    .span_after(mk_sp(self.block.span.hi(), else_block.span.lo()), "else"),
-                else_block.span.lo(),
-            );
-            let after_else_comment = extract_comment(after_else, context, shape);
-
-            let between_sep = match context.config.control_brace_style() {
-                ControlBraceStyle::AlwaysNextLine | ControlBraceStyle::ClosingNextLine => {
-                    &*alt_block_sep
-                }
-                ControlBraceStyle::AlwaysSameLine => " ",
-            };
-            let after_sep = match context.config.control_brace_style() {
-                ControlBraceStyle::AlwaysNextLine if last_in_chain => &*alt_block_sep,
-                _ => " ",
-            };
-
-            result.push_str(&format!(
-                "{}else{}",
-                between_kwd_else_block_comment
-                    .as_ref()
-                    .map_or(between_sep, |s| &**s),
-                after_else_comment.as_ref().map_or(after_sep, |s| &**s),
-            ));
-            result.push_str(&rewrite?);
-        }
-
-        Some(result)
-    }
-}
-
-fn rewrite_label(opt_label: Option<ast::Label>) -> Cow<'static, str> {
-    match opt_label {
-        Some(label) => Cow::from(format!("{}: ", label.ident)),
-        None => Cow::from(""),
-    }
-}
-
-fn extract_comment(span: Span, context: &RewriteContext, shape: Shape) -> Option<String> {
-    match rewrite_missing_comment(span, shape, context) {
-        Some(ref comment) if !comment.is_empty() => Some(format!(
-            "\n{indent}{}\n{indent}",
-            comment,
-            indent = shape.indent.to_string(context.config)
-        )),
-        _ => None,
-    }
-}
-
-pub fn block_contains_comment(block: &ast::Block, codemap: &CodeMap) -> bool {
-    let snippet = codemap.span_to_snippet(block.span).unwrap();
-    contains_comment(&snippet)
-}
-
-// Checks that a block contains no statements, an expression and no comments.
-// FIXME: incorrectly returns false when comment is contained completely within
-// the expression.
-pub fn is_simple_block(block: &ast::Block, codemap: &CodeMap) -> bool {
-    (block.stmts.len() == 1 && stmt_is_expr(&block.stmts[0])
-        && !block_contains_comment(block, codemap))
-}
-
-/// Checks whether a block contains at most one statement or expression, and no comments.
-pub fn is_simple_block_stmt(block: &ast::Block, codemap: &CodeMap) -> bool {
-    block.stmts.len() <= 1 && !block_contains_comment(block, codemap)
-}
-
-/// Checks whether a block contains no statements, expressions, or comments.
-pub fn is_empty_block(block: &ast::Block, codemap: &CodeMap) -> bool {
-    block.stmts.is_empty() && !block_contains_comment(block, codemap)
-}
-
-pub fn stmt_is_expr(stmt: &ast::Stmt) -> bool {
-    match stmt.node {
-        ast::StmtKind::Expr(..) => true,
-        _ => false,
-    }
-}
-
-pub fn is_unsafe_block(block: &ast::Block) -> bool {
-    if let ast::BlockCheckMode::Unsafe(..) = block.rules {
-        true
-    } else {
-        false
-    }
-}
-
-// A simple wrapper type against ast::Arm. Used inside write_list().
-struct ArmWrapper<'a> {
-    pub arm: &'a ast::Arm,
-    // True if the arm is the last one in match expression. Used to decide on whether we should add
-    // trailing comma to the match arm when `config.trailing_comma() == Never`.
-    pub is_last: bool,
-}
-
-impl<'a> ArmWrapper<'a> {
-    pub fn new(arm: &'a ast::Arm, is_last: bool) -> ArmWrapper<'a> {
-        ArmWrapper { arm, is_last }
-    }
-}
-
-impl<'a> Rewrite for ArmWrapper<'a> {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        rewrite_match_arm(context, self.arm, shape, self.is_last)
-    }
-}
-
-fn rewrite_match(
-    context: &RewriteContext,
-    cond: &ast::Expr,
-    arms: &[ast::Arm],
-    shape: Shape,
-    span: Span,
-    attrs: &[ast::Attribute],
-) -> Option<String> {
-    // Do not take the rhs overhead from the upper expressions into account
-    // when rewriting match condition.
-    let cond_shape = Shape {
-        width: context.budget(shape.used_width()),
-        ..shape
-    };
-    // 6 = `match `
-    let cond_shape = match context.config.indent_style() {
-        IndentStyle::Visual => cond_shape.shrink_left(6)?,
-        IndentStyle::Block => cond_shape.offset_left(6)?,
-    };
-    let cond_str = cond.rewrite(context, cond_shape)?;
-    let alt_block_sep = String::from("\n") + &shape.indent.to_string(context.config);
-    let block_sep = match context.config.control_brace_style() {
-        ControlBraceStyle::AlwaysNextLine => &alt_block_sep,
-        _ if last_line_extendable(&cond_str) => " ",
-        // 2 = ` {`
-        _ if cond_str.contains('\n') || cond_str.len() + 2 > cond_shape.width => &alt_block_sep,
-        _ => " ",
-    };
-
-    let nested_indent_str = shape
-        .indent
-        .block_indent(context.config)
-        .to_string(context.config);
-    // Inner attributes.
-    let inner_attrs = &inner_attributes(attrs);
-    let inner_attrs_str = if inner_attrs.is_empty() {
-        String::new()
-    } else {
-        inner_attrs
-            .rewrite(context, shape)
-            .map(|s| format!("{}{}\n", nested_indent_str, s))?
-    };
-
-    let open_brace_pos = if inner_attrs.is_empty() {
-        let hi = if arms.is_empty() {
-            span.hi()
-        } else {
-            arms[0].span().lo()
-        };
-        context.codemap.span_after(mk_sp(cond.span.hi(), hi), "{")
-    } else {
-        inner_attrs[inner_attrs.len() - 1].span().hi()
-    };
-
-    if arms.is_empty() {
-        let snippet = context.snippet(mk_sp(open_brace_pos, span.hi() - BytePos(1)));
-        if snippet.trim().is_empty() {
-            Some(format!("match {} {{}}", cond_str))
-        } else {
-            // Empty match with comments or inner attributes? We are not going to bother, sorry ;)
-            Some(context.snippet(span).to_owned())
-        }
-    } else {
-        Some(format!(
-            "match {}{}{{\n{}{}{}\n{}}}",
-            cond_str,
-            block_sep,
-            inner_attrs_str,
-            nested_indent_str,
-            rewrite_match_arms(context, arms, shape, span, open_brace_pos)?,
-            shape.indent.to_string(context.config),
-        ))
-    }
-}
-
-fn arm_comma(config: &Config, body: &ast::Expr, is_last: bool) -> &'static str {
-    if is_last && config.trailing_comma() == SeparatorTactic::Never {
-        ""
-    } else if config.match_block_trailing_comma() {
-        ","
-    } else if let ast::ExprKind::Block(ref block) = body.node {
-        if let ast::BlockCheckMode::Default = block.rules {
-            ""
-        } else {
-            ","
-        }
-    } else {
-        ","
-    }
-}
-
-fn rewrite_match_arms(
-    context: &RewriteContext,
-    arms: &[ast::Arm],
-    shape: Shape,
-    span: Span,
-    open_brace_pos: BytePos,
-) -> Option<String> {
-    let arm_shape = shape
-        .block_indent(context.config.tab_spaces())
-        .with_max_width(context.config);
-
-    let arm_len = arms.len();
-    let is_last_iter = repeat(false)
-        .take(arm_len.checked_sub(1).unwrap_or(0))
-        .chain(repeat(true));
-    let items = itemize_list(
-        context.codemap,
-        arms.iter()
-            .zip(is_last_iter)
-            .map(|(arm, is_last)| ArmWrapper::new(arm, is_last)),
-        "}",
-        "|",
-        |arm| arm.arm.span().lo(),
-        |arm| arm.arm.span().hi(),
-        |arm| arm.rewrite(context, arm_shape),
-        open_brace_pos,
-        span.hi(),
-        false,
-    );
-    let arms_vec: Vec<_> = items.collect();
-    let fmt = ListFormatting {
-        tactic: DefinitiveListTactic::Vertical,
-        // We will add/remove commas inside `arm.rewrite()`, and hence no separator here.
-        separator: "",
-        trailing_separator: SeparatorTactic::Never,
-        separator_place: SeparatorPlace::Back,
-        shape: arm_shape,
-        ends_with_newline: true,
-        preserve_newline: true,
-        config: context.config,
-    };
-
-    write_list(&arms_vec, &fmt)
-}
-
-fn rewrite_match_arm(
-    context: &RewriteContext,
-    arm: &ast::Arm,
-    shape: Shape,
-    is_last: bool,
-) -> Option<String> {
-    let (missing_span, attrs_str) = if !arm.attrs.is_empty() {
-        if contains_skip(&arm.attrs) {
-            let (_, body) = flatten_arm_body(context, &arm.body);
-            // `arm.span()` does not include trailing comma, add it manually.
-            return Some(format!(
-                "{}{}",
-                context.snippet(arm.span()),
-                arm_comma(context.config, body, is_last),
-            ));
-        }
-        let missing_span = mk_sp(
-            arm.attrs[arm.attrs.len() - 1].span.hi(),
-            arm.pats[0].span.lo(),
-        );
-        (missing_span, arm.attrs.rewrite(context, shape)?)
-    } else {
-        (mk_sp(arm.span().lo(), arm.span().lo()), String::new())
-    };
-    let pats_str =
-        rewrite_match_pattern(context, &arm.pats, &arm.guard, shape).and_then(|pats_str| {
-            combine_strs_with_missing_comments(
-                context,
-                &attrs_str,
-                &pats_str,
-                missing_span,
-                shape,
-                false,
-            )
-        })?;
-    rewrite_match_body(
-        context,
-        &arm.body,
-        &pats_str,
-        shape,
-        arm.guard.is_some(),
-        is_last,
-    )
-}
-
-/// Returns true if the given pattern is short. A short pattern is defined by the following grammer:
-///
-/// [small, ntp]:
-///     - single token
-///     - `&[single-line, ntp]`
-///
-/// [small]:
-///     - `[small, ntp]`
-///     - unary tuple constructor `([small, ntp])`
-///     - `&[small]`
-fn is_short_pattern(pat: &ast::Pat, pat_str: &str) -> bool {
-    // We also require that the pattern is reasonably 'small' with its literal width.
-    pat_str.len() <= 20 && !pat_str.contains('\n') && is_short_pattern_inner(pat)
-}
-
-fn is_short_pattern_inner(pat: &ast::Pat) -> bool {
-    match pat.node {
-        ast::PatKind::Wild | ast::PatKind::Lit(_) => true,
-        ast::PatKind::Ident(_, _, ref pat) => pat.is_none(),
-        ast::PatKind::Struct(..)
-        | ast::PatKind::Mac(..)
-        | ast::PatKind::Slice(..)
-        | ast::PatKind::Path(..)
-        | ast::PatKind::Range(..) => false,
-        ast::PatKind::Tuple(ref subpats, _) => subpats.len() <= 1,
-        ast::PatKind::TupleStruct(ref path, ref subpats, _) => {
-            path.segments.len() <= 1 && subpats.len() <= 1
-        }
-        ast::PatKind::Box(ref p) | ast::PatKind::Ref(ref p, _) => is_short_pattern_inner(&*p),
-    }
-}
-
-fn rewrite_match_pattern(
-    context: &RewriteContext,
-    pats: &[ptr::P<ast::Pat>],
-    guard: &Option<ptr::P<ast::Expr>>,
-    shape: Shape,
-) -> Option<String> {
-    // Patterns
-    // 5 = ` => {`
-    let pat_shape = shape.sub_width(5)?;
-
-    let pat_strs = pats.iter()
-        .map(|p| p.rewrite(context, pat_shape))
-        .collect::<Option<Vec<_>>>()?;
-
-    let use_mixed_layout = pats.iter()
-        .zip(pat_strs.iter())
-        .all(|(pat, pat_str)| is_short_pattern(pat, pat_str));
-    let items: Vec<_> = pat_strs.into_iter().map(ListItem::from_str).collect();
-    let tactic = if use_mixed_layout {
-        DefinitiveListTactic::Mixed
-    } else {
-        definitive_tactic(
-            &items,
-            ListTactic::HorizontalVertical,
-            Separator::VerticalBar,
-            pat_shape.width,
-        )
-    };
-    let fmt = ListFormatting {
-        tactic,
-        separator: " |",
-        trailing_separator: SeparatorTactic::Never,
-        separator_place: context.config.binop_separator(),
-        shape: pat_shape,
-        ends_with_newline: false,
-        preserve_newline: false,
-        config: context.config,
-    };
-    let pats_str = write_list(&items, &fmt)?;
-
-    // Guard
-    let guard_str = rewrite_guard(context, guard, shape, trimmed_last_line_width(&pats_str))?;
-
-    Some(format!("{}{}", pats_str, guard_str))
-}
-
-// (extend, body)
-// @extend: true if the arm body can be put next to `=>`
-// @body: flattened body, if the body is block with a single expression
-fn flatten_arm_body<'a>(context: &'a RewriteContext, body: &'a ast::Expr) -> (bool, &'a ast::Expr) {
-    match body.node {
-        ast::ExprKind::Block(ref block)
-            if !is_unsafe_block(block) && is_simple_block(block, context.codemap) =>
-        {
-            if let ast::StmtKind::Expr(ref expr) = block.stmts[0].node {
-                (
-                    !context.config.force_multiline_blocks() && can_extend_match_arm_body(expr),
-                    &*expr,
-                )
-            } else {
-                (false, &*body)
-            }
-        }
-        _ => (
-            !context.config.force_multiline_blocks() && body.can_be_overflowed(context, 1),
-            &*body,
-        ),
-    }
-}
-
-fn rewrite_match_body(
-    context: &RewriteContext,
-    body: &ptr::P<ast::Expr>,
-    pats_str: &str,
-    shape: Shape,
-    has_guard: bool,
-    is_last: bool,
-) -> Option<String> {
-    let (extend, body) = flatten_arm_body(context, body);
-    let (is_block, is_empty_block) = if let ast::ExprKind::Block(ref block) = body.node {
-        (true, is_empty_block(block, context.codemap))
-    } else {
-        (false, false)
-    };
-
-    let comma = arm_comma(context.config, body, is_last);
-    let alt_block_sep = String::from("\n") + &shape.indent.to_string(context.config);
-    let alt_block_sep = alt_block_sep.as_str();
-
-    let combine_orig_body = |body_str: &str| {
-        let block_sep = match context.config.control_brace_style() {
-            ControlBraceStyle::AlwaysNextLine if is_block => alt_block_sep,
-            _ => " ",
-        };
-
-        Some(format!("{} =>{}{}{}", pats_str, block_sep, body_str, comma))
-    };
-
-    let forbid_same_line = has_guard && pats_str.contains('\n') && !is_empty_block;
-    let next_line_indent = if !is_block || is_empty_block {
-        shape.indent.block_indent(context.config)
-    } else {
-        shape.indent
-    };
-    let combine_next_line_body = |body_str: &str| {
-        if is_block {
-            return Some(format!(
-                "{} =>\n{}{}",
-                pats_str,
-                next_line_indent.to_string(context.config),
-                body_str
-            ));
-        }
-
-        let indent_str = shape.indent.to_string(context.config);
-        let nested_indent_str = next_line_indent.to_string(context.config);
-        let (body_prefix, body_suffix) = if context.config.match_arm_blocks() {
-            let comma = if context.config.match_block_trailing_comma() {
-                ","
-            } else {
-                ""
-            };
-            ("{", format!("\n{}}}{}", indent_str, comma))
-        } else {
-            ("", String::from(","))
-        };
-
-        let block_sep = match context.config.control_brace_style() {
-            ControlBraceStyle::AlwaysNextLine => format!("{}{}\n", alt_block_sep, body_prefix),
-            _ if body_prefix.is_empty() => "\n".to_owned(),
-            _ if forbid_same_line => format!("{}{}\n", alt_block_sep, body_prefix),
-            _ => format!(" {}\n", body_prefix),
-        } + &nested_indent_str;
-
-        Some(format!(
-            "{} =>{}{}{}",
-            pats_str, block_sep, body_str, body_suffix
-        ))
-    };
-
-    // Let's try and get the arm body on the same line as the condition.
-    // 4 = ` => `.len()
-    let orig_body_shape = shape
-        .offset_left(extra_offset(pats_str, shape) + 4)
-        .and_then(|shape| shape.sub_width(comma.len()));
-    let orig_body = if let Some(body_shape) = orig_body_shape {
-        let rewrite = nop_block_collapse(
-            format_expr(body, ExprType::Statement, context, body_shape),
-            body_shape.width,
-        );
-
-        match rewrite {
-            Some(ref body_str)
-                if !forbid_same_line
-                    && (is_block
-                        || (!body_str.contains('\n') && body_str.len() <= body_shape.width)) =>
-            {
-                return combine_orig_body(body_str);
-            }
-            _ => rewrite,
-        }
-    } else {
-        None
-    };
-    let orig_budget = orig_body_shape.map_or(0, |shape| shape.width);
-
-    // Try putting body on the next line and see if it looks better.
-    let next_line_body_shape = Shape::indented(next_line_indent, context.config);
-    let next_line_body = nop_block_collapse(
-        format_expr(body, ExprType::Statement, context, next_line_body_shape),
-        next_line_body_shape.width,
-    );
-    match (orig_body, next_line_body) {
-        (Some(ref orig_str), Some(ref next_line_str))
-            if forbid_same_line || prefer_next_line(orig_str, next_line_str) =>
-        {
-            combine_next_line_body(next_line_str)
-        }
-        (Some(ref orig_str), _) if extend && first_line_width(orig_str) <= orig_budget => {
-            combine_orig_body(orig_str)
-        }
-        (Some(ref orig_str), Some(ref next_line_str)) if orig_str.contains('\n') => {
-            combine_next_line_body(next_line_str)
-        }
-        (None, Some(ref next_line_str)) => combine_next_line_body(next_line_str),
-        (None, None) => None,
-        (Some(ref orig_str), _) => combine_orig_body(orig_str),
-    }
-}
-
-// The `if ...` guard on a match arm.
-fn rewrite_guard(
-    context: &RewriteContext,
-    guard: &Option<ptr::P<ast::Expr>>,
-    shape: Shape,
-    // The amount of space used up on this line for the pattern in
-    // the arm (excludes offset).
-    pattern_width: usize,
-) -> Option<String> {
-    if let Some(ref guard) = *guard {
-        // First try to fit the guard string on the same line as the pattern.
-        // 4 = ` if `, 5 = ` => {`
-        let cond_shape = shape
-            .offset_left(pattern_width + 4)
-            .and_then(|s| s.sub_width(5));
-        if let Some(cond_shape) = cond_shape {
-            if let Some(cond_str) = guard.rewrite(context, cond_shape) {
-                if !cond_str.contains('\n') || pattern_width <= context.config.tab_spaces() {
-                    return Some(format!(" if {}", cond_str));
-                }
-            }
-        }
-
-        // Not enough space to put the guard after the pattern, try a newline.
-        // 3 = `if `, 5 = ` => {`
-        let cond_shape = Shape::indented(shape.indent.block_indent(context.config), context.config)
-            .offset_left(3)
-            .and_then(|s| s.sub_width(5));
-        if let Some(cond_shape) = cond_shape {
-            if let Some(cond_str) = guard.rewrite(context, cond_shape) {
-                return Some(format!(
-                    "\n{}if {}",
-                    cond_shape.indent.to_string(context.config),
-                    cond_str
-                ));
-            }
-        }
-
-        None
-    } else {
-        Some(String::new())
-    }
-}
-
-fn rewrite_pat_expr(
-    context: &RewriteContext,
-    pat: Option<&ast::Pat>,
-    expr: &ast::Expr,
-    matcher: &str,
-    // Connecting piece between pattern and expression,
-    // *without* trailing space.
-    connector: &str,
-    keyword: &str,
-    shape: Shape,
-    offset: usize,
-) -> Option<String> {
-    debug!("rewrite_pat_expr {:?} {:?} {:?}", shape, pat, expr);
-    let cond_shape = shape.offset_left(offset)?;
-    if let Some(pat) = pat {
-        let matcher = if matcher.is_empty() {
-            matcher.to_owned()
-        } else {
-            format!("{} ", matcher)
-        };
-        let pat_shape = cond_shape
-            .offset_left(matcher.len())?
-            .sub_width(connector.len())?;
-        let pat_string = pat.rewrite(context, pat_shape)?;
-        let result = format!("{}{}{}", matcher, pat_string, connector);
-        return rewrite_assign_rhs(context, result, expr, cond_shape);
-    }
-
-    let expr_rw = expr.rewrite(context, cond_shape);
-    // The expression may (partially) fit on the current line.
-    // We do not allow splitting between `if` and condition.
-    if keyword == "if" || expr_rw.is_some() {
-        return expr_rw;
-    }
-
-    // The expression won't fit on the current line, jump to next.
-    let nested_shape = shape
-        .block_indent(context.config.tab_spaces())
-        .with_max_width(context.config);
-    let nested_indent_str = nested_shape.indent.to_string(context.config);
-    expr.rewrite(context, nested_shape)
-        .map(|expr_rw| format!("\n{}{}", nested_indent_str, expr_rw))
-}
-
-fn can_extend_match_arm_body(body: &ast::Expr) -> bool {
-    match body.node {
-        // We do not allow `if` to stay on the same line, since we could easily mistake
-        // `pat => if cond { ... }` and `pat if cond => { ... }`.
-        ast::ExprKind::If(..) | ast::ExprKind::IfLet(..) => false,
-        ast::ExprKind::ForLoop(..)
-        | ast::ExprKind::Loop(..)
-        | ast::ExprKind::While(..)
-        | ast::ExprKind::WhileLet(..)
-        | ast::ExprKind::Match(..)
-        | ast::ExprKind::Block(..)
-        | ast::ExprKind::Closure(..)
-        | ast::ExprKind::Array(..)
-        | ast::ExprKind::Call(..)
-        | ast::ExprKind::MethodCall(..)
-        | ast::ExprKind::Mac(..)
-        | ast::ExprKind::Struct(..)
-        | ast::ExprKind::Tup(..) => true,
-        ast::ExprKind::AddrOf(_, ref expr)
-        | ast::ExprKind::Box(ref expr)
-        | ast::ExprKind::Try(ref expr)
-        | ast::ExprKind::Unary(_, ref expr)
-        | ast::ExprKind::Cast(ref expr, _) => can_extend_match_arm_body(expr),
-        _ => false,
-    }
-}
-
-pub fn rewrite_literal(context: &RewriteContext, l: &ast::Lit, shape: Shape) -> Option<String> {
-    match l.node {
-        ast::LitKind::Str(_, ast::StrStyle::Cooked) => rewrite_string_lit(context, l.span, shape),
-        _ => wrap_str(
-            context.snippet(l.span).to_owned(),
-            context.config.max_width(),
-            shape,
-        ),
-    }
-}
-
-fn rewrite_string_lit(context: &RewriteContext, span: Span, shape: Shape) -> Option<String> {
-    let string_lit = context.snippet(span);
-
-    if !context.config.format_strings() {
-        if string_lit
-            .lines()
-            .rev()
-            .skip(1)
-            .all(|line| line.ends_with('\\'))
-        {
-            let new_indent = shape.visual_indent(1).indent;
-            let indented_string_lit = String::from(
-                string_lit
-                    .lines()
-                    .map(|line| {
-                        format!(
-                            "{}{}",
-                            new_indent.to_string(context.config),
-                            line.trim_left()
-                        )
-                    })
-                    .collect::<Vec<_>>()
-                    .join("\n")
-                    .trim_left(),
-            );
-            return wrap_str(indented_string_lit, context.config.max_width(), shape);
-        } else {
-            return wrap_str(string_lit.to_owned(), context.config.max_width(), shape);
-        }
-    }
-
-    // Remove the quote characters.
-    let str_lit = &string_lit[1..string_lit.len() - 1];
-
-    rewrite_string(
-        str_lit,
-        &StringFormat::new(shape.visual_indent(0), context.config),
-        None,
-    )
-}
-
-/// A list of `format!`-like macros, that take a long format string and a list of arguments to
-/// format.
-///
-/// Organized as a list of `(&str, usize)` tuples, giving the name of the macro and the number of
-/// arguments before the format string (none for `format!("format", ...)`, one for `assert!(result,
-/// "format", ...)`, two for `assert_eq!(left, right, "format", ...)`).
-const SPECIAL_MACRO_WHITELIST: &[(&str, usize)] = &[
-    // format! like macros
-    // From the Rust Standard Library.
-    ("eprint!", 0),
-    ("eprintln!", 0),
-    ("format!", 0),
-    ("format_args!", 0),
-    ("print!", 0),
-    ("println!", 0),
-    ("panic!", 0),
-    ("unreachable!", 0),
-    // From the `log` crate.
-    ("debug!", 0),
-    ("error!", 0),
-    ("info!", 0),
-    ("warn!", 0),
-    // write! like macros
-    ("assert!", 1),
-    ("debug_assert!", 1),
-    ("write!", 1),
-    ("writeln!", 1),
-    // assert_eq! like macros
-    ("assert_eq!", 2),
-    ("assert_ne!", 2),
-    ("debug_assert_eq!", 2),
-    ("debug_assert_ne!", 2),
-];
-
-pub fn rewrite_call(
-    context: &RewriteContext,
-    callee: &str,
-    args: &[ptr::P<ast::Expr>],
-    span: Span,
-    shape: Shape,
-) -> Option<String> {
-    let force_trailing_comma = if context.inside_macro {
-        span_ends_with_comma(context, span)
-    } else {
-        false
-    };
-    rewrite_call_inner(
-        context,
-        callee,
-        &ptr_vec_to_ref_vec(args),
-        span,
-        shape,
-        context.config.width_heuristics().fn_call_width,
-        force_trailing_comma,
-    )
-}
-
-pub fn rewrite_call_inner<'a, T>(
-    context: &RewriteContext,
-    callee_str: &str,
-    args: &[&T],
-    span: Span,
-    shape: Shape,
-    args_max_width: usize,
-    force_trailing_comma: bool,
-) -> Option<String>
-where
-    T: Rewrite + Spanned + ToExpr + 'a,
-{
-    // 2 = `( `, 1 = `(`
-    let paren_overhead = if context.config.spaces_within_parens_and_brackets() {
-        2
-    } else {
-        1
-    };
-    let used_width = extra_offset(callee_str, shape);
-    let one_line_width = shape.width.checked_sub(used_width + 2 * paren_overhead)?;
-
-    // 1 = "(" or ")"
-    let one_line_shape = shape
-        .offset_left(last_line_width(callee_str) + 1)?
-        .sub_width(1)?;
-    let nested_shape = shape_from_indent_style(
-        context,
-        shape,
-        used_width + 2 * paren_overhead,
-        used_width + paren_overhead,
-    )?;
-
-    let span_lo = context.codemap.span_after(span, "(");
-    let args_span = mk_sp(span_lo, span.hi());
-
-    let (extendable, list_str) = rewrite_call_args(
-        context,
-        args,
-        args_span,
-        one_line_shape,
-        nested_shape,
-        one_line_width,
-        args_max_width,
-        force_trailing_comma,
-        callee_str,
-    )?;
-
-    if !context.use_block_indent() && need_block_indent(&list_str, nested_shape) && !extendable {
-        let mut new_context = context.clone();
-        new_context.use_block = true;
-        return rewrite_call_inner(
-            &new_context,
-            callee_str,
-            args,
-            span,
-            shape,
-            args_max_width,
-            force_trailing_comma,
-        );
-    }
-
-    let args_shape = shape.sub_width(last_line_width(callee_str))?;
-    Some(format!(
-        "{}{}",
-        callee_str,
-        wrap_args_with_parens(context, &list_str, extendable, args_shape, nested_shape)
-    ))
-}
-
-fn need_block_indent(s: &str, shape: Shape) -> bool {
-    s.lines().skip(1).any(|s| {
-        s.find(|c| !char::is_whitespace(c))
-            .map_or(false, |w| w + 1 < shape.indent.width())
-    })
-}
-
-fn rewrite_call_args<'a, T>(
-    context: &RewriteContext,
-    args: &[&T],
-    span: Span,
-    one_line_shape: Shape,
-    nested_shape: Shape,
-    one_line_width: usize,
-    args_max_width: usize,
-    force_trailing_comma: bool,
-    callee_str: &str,
-) -> Option<(bool, String)>
-where
-    T: Rewrite + Spanned + ToExpr + 'a,
-{
-    let items = itemize_list(
-        context.codemap,
-        args.iter(),
-        ")",
-        ",",
-        |item| item.span().lo(),
-        |item| item.span().hi(),
-        |item| item.rewrite(context, nested_shape),
-        span.lo(),
-        span.hi(),
-        true,
-    );
-    let mut item_vec: Vec<_> = items.collect();
-
-    // Try letting the last argument overflow to the next line with block
-    // indentation. If its first line fits on one line with the other arguments,
-    // we format the function arguments horizontally.
-    let tactic = try_overflow_last_arg(
-        context,
-        &mut item_vec,
-        &args[..],
-        one_line_shape,
-        nested_shape,
-        one_line_width,
-        args_max_width,
-        callee_str,
-    );
-
-    let fmt = ListFormatting {
-        tactic,
-        separator: ",",
-        trailing_separator: if force_trailing_comma {
-            SeparatorTactic::Always
-        } else if context.inside_macro || !context.use_block_indent() {
-            SeparatorTactic::Never
-        } else {
-            context.config.trailing_comma()
-        },
-        separator_place: SeparatorPlace::Back,
-        shape: nested_shape,
-        ends_with_newline: context.use_block_indent() && tactic == DefinitiveListTactic::Vertical,
-        preserve_newline: false,
-        config: context.config,
-    };
-
-    write_list(&item_vec, &fmt)
-        .map(|args_str| (tactic == DefinitiveListTactic::Horizontal, args_str))
-}
-
-fn try_overflow_last_arg<'a, T>(
-    context: &RewriteContext,
-    item_vec: &mut Vec<ListItem>,
-    args: &[&T],
-    one_line_shape: Shape,
-    nested_shape: Shape,
-    one_line_width: usize,
-    args_max_width: usize,
-    callee_str: &str,
-) -> DefinitiveListTactic
-where
-    T: Rewrite + Spanned + ToExpr + 'a,
-{
-    // 1 = "("
-    let combine_arg_with_callee =
-        callee_str.len() + 1 <= context.config.tab_spaces() && args.len() == 1;
-    let overflow_last = combine_arg_with_callee || can_be_overflowed(context, args);
-
-    // Replace the last item with its first line to see if it fits with
-    // first arguments.
-    let placeholder = if overflow_last {
-        let mut context = context.clone();
-        if !combine_arg_with_callee {
-            if let Some(expr) = args[args.len() - 1].to_expr() {
-                if let ast::ExprKind::MethodCall(..) = expr.node {
-                    context.force_one_line_chain = true;
-                }
-            }
-        }
-        last_arg_shape(args, item_vec, one_line_shape, args_max_width).and_then(|arg_shape| {
-            rewrite_last_arg_with_overflow(&context, args, &mut item_vec[args.len() - 1], arg_shape)
-        })
-    } else {
-        None
-    };
-
-    let mut tactic = definitive_tactic(
-        &*item_vec,
-        ListTactic::LimitedHorizontalVertical(args_max_width),
-        Separator::Comma,
-        one_line_width,
-    );
-
-    // Replace the stub with the full overflowing last argument if the rewrite
-    // succeeded and its first line fits with the other arguments.
-    match (overflow_last, tactic, placeholder) {
-        (true, DefinitiveListTactic::Horizontal, Some(ref overflowed)) if args.len() == 1 => {
-            // When we are rewriting a nested function call, we restrict the
-            // bugdet for the inner function to avoid them being deeply nested.
-            // However, when the inner function has a prefix or a suffix
-            // (e.g. `foo() as u32`), this budget reduction may produce poorly
-            // formatted code, where a prefix or a suffix being left on its own
-            // line. Here we explicitlly check those cases.
-            if count_newlines(overflowed) == 1 {
-                let rw = args.last()
-                    .and_then(|last_arg| last_arg.rewrite(context, nested_shape));
-                let no_newline = rw.as_ref().map_or(false, |s| !s.contains('\n'));
-                if no_newline {
-                    item_vec[args.len() - 1].item = rw;
-                } else {
-                    item_vec[args.len() - 1].item = Some(overflowed.to_owned());
-                }
-            } else {
-                item_vec[args.len() - 1].item = Some(overflowed.to_owned());
-            }
-        }
-        (true, DefinitiveListTactic::Horizontal, placeholder @ Some(..)) => {
-            item_vec[args.len() - 1].item = placeholder;
-        }
-        _ if args.len() >= 1 => {
-            item_vec[args.len() - 1].item = args.last()
-                .and_then(|last_arg| last_arg.rewrite(context, nested_shape));
-
-            let default_tactic = || {
-                definitive_tactic(
-                    &*item_vec,
-                    ListTactic::LimitedHorizontalVertical(args_max_width),
-                    Separator::Comma,
-                    one_line_width,
-                )
-            };
-
-            // Use horizontal layout for a function with a single argument as long as
-            // everything fits in a single line.
-            if args.len() == 1
-                && args_max_width != 0 // Vertical layout is forced.
-                && !item_vec[0].has_comment()
-                && !item_vec[0].inner_as_ref().contains('\n')
-                && ::lists::total_item_width(&item_vec[0]) <= one_line_width
-            {
-                tactic = DefinitiveListTactic::Horizontal;
-            } else {
-                tactic = default_tactic();
-
-                if tactic == DefinitiveListTactic::Vertical {
-                    if let Some((all_simple, num_args_before)) =
-                        maybe_get_args_offset(callee_str, args)
-                    {
-                        let one_line = all_simple
-                            && definitive_tactic(
-                                &item_vec[..num_args_before],
-                                ListTactic::HorizontalVertical,
-                                Separator::Comma,
-                                nested_shape.width,
-                            ) == DefinitiveListTactic::Horizontal
-                            && definitive_tactic(
-                                &item_vec[num_args_before + 1..],
-                                ListTactic::HorizontalVertical,
-                                Separator::Comma,
-                                nested_shape.width,
-                            ) == DefinitiveListTactic::Horizontal;
-
-                        if one_line {
-                            tactic = DefinitiveListTactic::SpecialMacro(num_args_before);
-                        };
-                    }
-                }
-            }
-        }
-        _ => (),
-    }
-
-    tactic
-}
-
-fn is_simple_arg(expr: &ast::Expr) -> bool {
-    match expr.node {
-        ast::ExprKind::Lit(..) => true,
-        ast::ExprKind::Path(ref qself, ref path) => qself.is_none() && path.segments.len() <= 1,
-        ast::ExprKind::AddrOf(_, ref expr)
-        | ast::ExprKind::Box(ref expr)
-        | ast::ExprKind::Cast(ref expr, _)
-        | ast::ExprKind::Field(ref expr, _)
-        | ast::ExprKind::Try(ref expr)
-        | ast::ExprKind::TupField(ref expr, _)
-        | ast::ExprKind::Unary(_, ref expr) => is_simple_arg(expr),
-        ast::ExprKind::Index(ref lhs, ref rhs) | ast::ExprKind::Repeat(ref lhs, ref rhs) => {
-            is_simple_arg(lhs) && is_simple_arg(rhs)
-        }
-        _ => false,
-    }
-}
-
-fn is_every_args_simple<T: ToExpr>(lists: &[&T]) -> bool {
-    lists
-        .iter()
-        .all(|arg| arg.to_expr().map_or(false, is_simple_arg))
-}
-
-/// In case special-case style is required, returns an offset from which we start horizontal layout.
-fn maybe_get_args_offset<T: ToExpr>(callee_str: &str, args: &[&T]) -> Option<(bool, usize)> {
-    if let Some(&(_, num_args_before)) = SPECIAL_MACRO_WHITELIST
-        .iter()
-        .find(|&&(s, _)| s == callee_str)
-    {
-        let all_simple = args.len() > num_args_before && is_every_args_simple(args);
-
-        Some((all_simple, num_args_before))
-    } else {
-        None
-    }
-}
-
-/// Returns a shape for the last argument which is going to be overflowed.
-fn last_arg_shape<T>(
-    lists: &[&T],
-    items: &[ListItem],
-    shape: Shape,
-    args_max_width: usize,
-) -> Option<Shape>
-where
-    T: Rewrite + Spanned + ToExpr,
-{
-    let is_nested_call = lists
-        .iter()
-        .next()
-        .and_then(|item| item.to_expr())
-        .map_or(false, is_nested_call);
-    if items.len() == 1 && !is_nested_call {
-        return Some(shape);
-    }
-    let offset = items.iter().rev().skip(1).fold(0, |acc, i| {
-        // 2 = ", "
-        acc + 2 + i.inner_as_ref().len()
-    });
-    Shape {
-        width: min(args_max_width, shape.width),
-        ..shape
-    }.offset_left(offset)
-}
-
-fn rewrite_last_arg_with_overflow<'a, T>(
-    context: &RewriteContext,
-    args: &[&T],
-    last_item: &mut ListItem,
-    shape: Shape,
-) -> Option<String>
-where
-    T: Rewrite + Spanned + ToExpr + 'a,
-{
-    let last_arg = args[args.len() - 1];
-    let rewrite = if let Some(expr) = last_arg.to_expr() {
-        match expr.node {
-            // When overflowing the closure which consists of a single control flow expression,
-            // force to use block if its condition uses multi line.
-            ast::ExprKind::Closure(..) => {
-                // If the argument consists of multiple closures, we do not overflow
-                // the last closure.
-                if closures::args_have_many_closure(args) {
-                    None
-                } else {
-                    closures::rewrite_last_closure(context, expr, shape)
-                }
-            }
-            _ => expr.rewrite(context, shape),
-        }
-    } else {
-        last_arg.rewrite(context, shape)
-    };
-
-    if let Some(rewrite) = rewrite {
-        let rewrite_first_line = Some(rewrite[..first_line_width(&rewrite)].to_owned());
-        last_item.item = rewrite_first_line;
-        Some(rewrite)
-    } else {
-        None
-    }
-}
-
-fn can_be_overflowed<'a, T>(context: &RewriteContext, args: &[&T]) -> bool
-where
-    T: Rewrite + Spanned + ToExpr + 'a,
-{
-    args.last()
-        .map_or(false, |x| x.can_be_overflowed(context, args.len()))
-}
-
-pub fn can_be_overflowed_expr(context: &RewriteContext, expr: &ast::Expr, args_len: usize) -> bool {
-    match expr.node {
-        ast::ExprKind::Match(..) => {
-            (context.use_block_indent() && args_len == 1)
-                || (context.config.indent_style() == IndentStyle::Visual && args_len > 1)
-        }
-        ast::ExprKind::If(..)
-        | ast::ExprKind::IfLet(..)
-        | ast::ExprKind::ForLoop(..)
-        | ast::ExprKind::Loop(..)
-        | ast::ExprKind::While(..)
-        | ast::ExprKind::WhileLet(..) => {
-            context.config.combine_control_expr() && context.use_block_indent() && args_len == 1
-        }
-        ast::ExprKind::Block(..) | ast::ExprKind::Closure(..) => {
-            context.use_block_indent()
-                || context.config.indent_style() == IndentStyle::Visual && args_len > 1
-        }
-        ast::ExprKind::Array(..)
-        | ast::ExprKind::Call(..)
-        | ast::ExprKind::Mac(..)
-        | ast::ExprKind::MethodCall(..)
-        | ast::ExprKind::Struct(..)
-        | ast::ExprKind::Tup(..) => context.use_block_indent() && args_len == 1,
-        ast::ExprKind::AddrOf(_, ref expr)
-        | ast::ExprKind::Box(ref expr)
-        | ast::ExprKind::Try(ref expr)
-        | ast::ExprKind::Unary(_, ref expr)
-        | ast::ExprKind::Cast(ref expr, _) => can_be_overflowed_expr(context, expr, args_len),
-        _ => false,
-    }
-}
-
-fn is_nested_call(expr: &ast::Expr) -> bool {
-    match expr.node {
-        ast::ExprKind::Call(..) | ast::ExprKind::Mac(..) => true,
-        ast::ExprKind::AddrOf(_, ref expr)
-        | ast::ExprKind::Box(ref expr)
-        | ast::ExprKind::Try(ref expr)
-        | ast::ExprKind::Unary(_, ref expr)
-        | ast::ExprKind::Cast(ref expr, _) => is_nested_call(expr),
-        _ => false,
-    }
-}
-
-pub fn wrap_args_with_parens(
-    context: &RewriteContext,
-    args_str: &str,
-    is_extendable: bool,
-    shape: Shape,
-    nested_shape: Shape,
-) -> String {
-    if !context.use_block_indent()
-        || (context.inside_macro && !args_str.contains('\n')
-            && args_str.len() + paren_overhead(context) <= shape.width) || is_extendable
-    {
-        if context.config.spaces_within_parens_and_brackets() && !args_str.is_empty() {
-            format!("( {} )", args_str)
-        } else {
-            format!("({})", args_str)
-        }
-    } else {
-        format!(
-            "(\n{}{}\n{})",
-            nested_shape.indent.to_string(context.config),
-            args_str,
-            shape.block().indent.to_string(context.config)
-        )
-    }
-}
-
-/// Return true if a function call or a method call represented by the given span ends with a
-/// trailing comma. This function is used when rewriting macro, as adding or removing a trailing
-/// comma from macro can potentially break the code.
-fn span_ends_with_comma(context: &RewriteContext, span: Span) -> bool {
-    let mut encountered_closing_paren = false;
-    for c in context.snippet(span).chars().rev() {
-        match c {
-            ',' => return true,
-            ')' => if encountered_closing_paren {
-                return false;
-            } else {
-                encountered_closing_paren = true;
-            },
-            _ if c.is_whitespace() => continue,
-            _ => return false,
-        }
-    }
-    false
-}
-
-fn rewrite_paren(context: &RewriteContext, subexpr: &ast::Expr, shape: Shape) -> Option<String> {
-    debug!("rewrite_paren, shape: {:?}", shape);
-    let total_paren_overhead = paren_overhead(context);
-    let paren_overhead = total_paren_overhead / 2;
-    let sub_shape = shape
-        .offset_left(paren_overhead)
-        .and_then(|s| s.sub_width(paren_overhead))?;
-
-    let paren_wrapper = |s: &str| {
-        if context.config.spaces_within_parens_and_brackets() && !s.is_empty() {
-            format!("( {} )", s)
-        } else {
-            format!("({})", s)
-        }
-    };
-
-    let subexpr_str = subexpr.rewrite(context, sub_shape)?;
-    debug!("rewrite_paren, subexpr_str: `{:?}`", subexpr_str);
-
-    if subexpr_str.contains('\n')
-        || first_line_width(&subexpr_str) + total_paren_overhead <= shape.width
-    {
-        Some(paren_wrapper(&subexpr_str))
-    } else {
-        None
-    }
-}
-
-fn rewrite_index(
-    expr: &ast::Expr,
-    index: &ast::Expr,
-    context: &RewriteContext,
-    shape: Shape,
-) -> Option<String> {
-    let expr_str = expr.rewrite(context, shape)?;
-
-    let (lbr, rbr) = if context.config.spaces_within_parens_and_brackets() {
-        ("[ ", " ]")
-    } else {
-        ("[", "]")
-    };
-
-    let offset = last_line_width(&expr_str) + lbr.len();
-    let rhs_overhead = shape.rhs_overhead(context.config);
-    let index_shape = if expr_str.contains('\n') {
-        Shape::legacy(context.config.max_width(), shape.indent)
-            .offset_left(offset)
-            .and_then(|shape| shape.sub_width(rbr.len() + rhs_overhead))
-    } else {
-        shape.visual_indent(offset).sub_width(offset + rbr.len())
-    };
-    let orig_index_rw = index_shape.and_then(|s| index.rewrite(context, s));
-
-    // Return if index fits in a single line.
-    match orig_index_rw {
-        Some(ref index_str) if !index_str.contains('\n') => {
-            return Some(format!("{}{}{}{}", expr_str, lbr, index_str, rbr));
-        }
-        _ => (),
-    }
-
-    // Try putting index on the next line and see if it fits in a single line.
-    let indent = shape.indent.block_indent(context.config);
-    let index_shape = Shape::indented(indent, context.config).offset_left(lbr.len())?;
-    let index_shape = index_shape.sub_width(rbr.len() + rhs_overhead)?;
-    let new_index_rw = index.rewrite(context, index_shape);
-    match (orig_index_rw, new_index_rw) {
-        (_, Some(ref new_index_str)) if !new_index_str.contains('\n') => Some(format!(
-            "{}\n{}{}{}{}",
-            expr_str,
-            indent.to_string(context.config),
-            lbr,
-            new_index_str,
-            rbr
-        )),
-        (None, Some(ref new_index_str)) => Some(format!(
-            "{}\n{}{}{}{}",
-            expr_str,
-            indent.to_string(context.config),
-            lbr,
-            new_index_str,
-            rbr
-        )),
-        (Some(ref index_str), _) => Some(format!("{}{}{}{}", expr_str, lbr, index_str, rbr)),
-        _ => None,
-    }
-}
-
-fn struct_lit_can_be_aligned(fields: &[ast::Field], base: &Option<&ast::Expr>) -> bool {
-    if base.is_some() {
-        return false;
-    }
-
-    fields.iter().all(|field| !field.is_shorthand)
-}
-
-fn rewrite_struct_lit<'a>(
-    context: &RewriteContext,
-    path: &ast::Path,
-    fields: &'a [ast::Field],
-    base: Option<&'a ast::Expr>,
-    span: Span,
-    shape: Shape,
-) -> Option<String> {
-    debug!("rewrite_struct_lit: shape {:?}", shape);
-
-    enum StructLitField<'a> {
-        Regular(&'a ast::Field),
-        Base(&'a ast::Expr),
-    }
-
-    // 2 = " {".len()
-    let path_shape = shape.sub_width(2)?;
-    let path_str = rewrite_path(context, PathContext::Expr, None, path, path_shape)?;
-
-    if fields.is_empty() && base.is_none() {
-        return Some(format!("{} {{}}", path_str));
-    }
-
-    // Foo { a: Foo } - indent is +3, width is -5.
-    let (h_shape, v_shape) = struct_lit_shape(shape, context, path_str.len() + 3, 2)?;
-
-    let one_line_width = h_shape.map_or(0, |shape| shape.width);
-    let body_lo = context.codemap.span_after(span, "{");
-    let fields_str = if struct_lit_can_be_aligned(fields, &base)
-        && context.config.struct_field_align_threshold() > 0
-    {
-        rewrite_with_alignment(
-            fields,
-            context,
-            shape,
-            mk_sp(body_lo, span.hi()),
-            one_line_width,
-        )?
-    } else {
-        let field_iter = fields
-            .into_iter()
-            .map(StructLitField::Regular)
-            .chain(base.into_iter().map(StructLitField::Base));
-
-        let span_lo = |item: &StructLitField| match *item {
-            StructLitField::Regular(field) => field.span().lo(),
-            StructLitField::Base(expr) => {
-                let last_field_hi = fields.last().map_or(span.lo(), |field| field.span.hi());
-                let snippet = context.snippet(mk_sp(last_field_hi, expr.span.lo()));
-                let pos = snippet.find_uncommented("..").unwrap();
-                last_field_hi + BytePos(pos as u32)
-            }
-        };
-        let span_hi = |item: &StructLitField| match *item {
-            StructLitField::Regular(field) => field.span().hi(),
-            StructLitField::Base(expr) => expr.span.hi(),
-        };
-        let rewrite = |item: &StructLitField| match *item {
-            StructLitField::Regular(field) => {
-                // The 1 taken from the v_budget is for the comma.
-                rewrite_field(context, field, v_shape.sub_width(1)?, 0)
-            }
-            StructLitField::Base(expr) => {
-                // 2 = ..
-                expr.rewrite(context, v_shape.offset_left(2)?)
-                    .map(|s| format!("..{}", s))
-            }
-        };
-
-        let items = itemize_list(
-            context.codemap,
-            field_iter,
-            "}",
-            ",",
-            span_lo,
-            span_hi,
-            rewrite,
-            body_lo,
-            span.hi(),
-            false,
-        );
-        let item_vec = items.collect::<Vec<_>>();
-
-        let tactic = struct_lit_tactic(h_shape, context, &item_vec);
-        let nested_shape = shape_for_tactic(tactic, h_shape, v_shape);
-        let fmt = struct_lit_formatting(nested_shape, tactic, context, base.is_some());
-
-        write_list(&item_vec, &fmt)?
-    };
-
-    let fields_str = wrap_struct_field(context, &fields_str, shape, v_shape, one_line_width);
-    Some(format!("{} {{{}}}", path_str, fields_str))
-
-    // FIXME if context.config.indent_style() == Visual, but we run out
-    // of space, we should fall back to BlockIndent.
-}
-
-pub fn wrap_struct_field(
-    context: &RewriteContext,
-    fields_str: &str,
-    shape: Shape,
-    nested_shape: Shape,
-    one_line_width: usize,
-) -> String {
-    if context.config.indent_style() == IndentStyle::Block
-        && (fields_str.contains('\n') || !context.config.struct_lit_single_line()
-            || fields_str.len() > one_line_width)
-    {
-        format!(
-            "\n{}{}\n{}",
-            nested_shape.indent.to_string(context.config),
-            fields_str,
-            shape.indent.to_string(context.config)
-        )
-    } else {
-        // One liner or visual indent.
-        format!(" {} ", fields_str)
-    }
-}
-
-pub fn struct_lit_field_separator(config: &Config) -> &str {
-    colon_spaces(config.space_before_colon(), config.space_after_colon())
-}
-
-pub fn rewrite_field(
-    context: &RewriteContext,
-    field: &ast::Field,
-    shape: Shape,
-    prefix_max_width: usize,
-) -> Option<String> {
-    if contains_skip(&field.attrs) {
-        return Some(context.snippet(field.span()).to_owned());
-    }
-    let mut attrs_str = field.attrs.rewrite(context, shape)?;
-    if !attrs_str.is_empty() {
-        attrs_str.push_str(&format!("\n{}", shape.indent.to_string(context.config)));
-    };
-    let name = field.ident.node.to_string();
-    if field.is_shorthand {
-        Some(attrs_str + &name)
-    } else {
-        let mut separator = String::from(struct_lit_field_separator(context.config));
-        for _ in 0..prefix_max_width.checked_sub(name.len()).unwrap_or(0) {
-            separator.push(' ');
-        }
-        let overhead = name.len() + separator.len();
-        let expr_shape = shape.offset_left(overhead)?;
-        let expr = field.expr.rewrite(context, expr_shape);
-
-        match expr {
-            Some(ref e) if e.as_str() == name && context.config.use_field_init_shorthand() => {
-                Some(attrs_str + &name)
-            }
-            Some(e) => Some(format!("{}{}{}{}", attrs_str, name, separator, e)),
-            None => {
-                let expr_offset = shape.indent.block_indent(context.config);
-                let expr = field
-                    .expr
-                    .rewrite(context, Shape::indented(expr_offset, context.config));
-                expr.map(|s| {
-                    format!(
-                        "{}{}:\n{}{}",
-                        attrs_str,
-                        name,
-                        expr_offset.to_string(context.config),
-                        s
-                    )
-                })
-            }
-        }
-    }
-}
-
-fn shape_from_indent_style(
-    context: &RewriteContext,
-    shape: Shape,
-    overhead: usize,
-    offset: usize,
-) -> Option<Shape> {
-    if context.use_block_indent() {
-        // 1 = ","
-        shape
-            .block()
-            .block_indent(context.config.tab_spaces())
-            .with_max_width(context.config)
-            .sub_width(1)
-    } else {
-        shape.visual_indent(offset).sub_width(overhead)
-    }
-}
-
-fn rewrite_tuple_in_visual_indent_style<'a, T>(
-    context: &RewriteContext,
-    items: &[&T],
-    span: Span,
-    shape: Shape,
-) -> Option<String>
-where
-    T: Rewrite + Spanned + ToExpr + 'a,
-{
-    let mut items = items.iter();
-    // In case of length 1, need a trailing comma
-    debug!("rewrite_tuple_in_visual_indent_style {:?}", shape);
-    if items.len() == 1 {
-        // 3 = "(" + ",)"
-        let nested_shape = shape.sub_width(3)?.visual_indent(1);
-        return items
-            .next()
-            .unwrap()
-            .rewrite(context, nested_shape)
-            .map(|s| {
-                if context.config.spaces_within_parens_and_brackets() {
-                    format!("( {}, )", s)
-                } else {
-                    format!("({},)", s)
-                }
-            });
-    }
-
-    let list_lo = context.codemap.span_after(span, "(");
-    let nested_shape = shape.sub_width(2)?.visual_indent(1);
-    let items = itemize_list(
-        context.codemap,
-        items,
-        ")",
-        ",",
-        |item| item.span().lo(),
-        |item| item.span().hi(),
-        |item| item.rewrite(context, nested_shape),
-        list_lo,
-        span.hi() - BytePos(1),
-        false,
-    );
-    let item_vec: Vec<_> = items.collect();
-    let tactic = definitive_tactic(
-        &item_vec,
-        ListTactic::HorizontalVertical,
-        Separator::Comma,
-        nested_shape.width,
-    );
-    let fmt = ListFormatting {
-        tactic,
-        separator: ",",
-        trailing_separator: SeparatorTactic::Never,
-        separator_place: SeparatorPlace::Back,
-        shape,
-        ends_with_newline: false,
-        preserve_newline: false,
-        config: context.config,
-    };
-    let list_str = write_list(&item_vec, &fmt)?;
-
-    if context.config.spaces_within_parens_and_brackets() && !list_str.is_empty() {
-        Some(format!("( {} )", list_str))
-    } else {
-        Some(format!("({})", list_str))
-    }
-}
-
-pub fn rewrite_tuple<'a, T>(
-    context: &RewriteContext,
-    items: &[&T],
-    span: Span,
-    shape: Shape,
-) -> Option<String>
-where
-    T: Rewrite + Spanned + ToExpr + 'a,
-{
-    debug!("rewrite_tuple {:?}", shape);
-    if context.use_block_indent() {
-        // We use the same rule as function calls for rewriting tuples.
-        let force_trailing_comma = if context.inside_macro {
-            span_ends_with_comma(context, span)
-        } else {
-            items.len() == 1
-        };
-        rewrite_call_inner(
-            context,
-            &String::new(),
-            items,
-            span,
-            shape,
-            context.config.width_heuristics().fn_call_width,
-            force_trailing_comma,
-        )
-    } else {
-        rewrite_tuple_in_visual_indent_style(context, items, span, shape)
-    }
-}
-
-pub fn rewrite_unary_prefix<R: Rewrite>(
-    context: &RewriteContext,
-    prefix: &str,
-    rewrite: &R,
-    shape: Shape,
-) -> Option<String> {
-    rewrite
-        .rewrite(context, shape.offset_left(prefix.len())?)
-        .map(|r| format!("{}{}", prefix, r))
-}
-
-// FIXME: this is probably not correct for multi-line Rewrites. we should
-// subtract suffix.len() from the last line budget, not the first!
-pub fn rewrite_unary_suffix<R: Rewrite>(
-    context: &RewriteContext,
-    suffix: &str,
-    rewrite: &R,
-    shape: Shape,
-) -> Option<String> {
-    rewrite
-        .rewrite(context, shape.sub_width(suffix.len())?)
-        .map(|mut r| {
-            r.push_str(suffix);
-            r
-        })
-}
-
-fn rewrite_unary_op(
-    context: &RewriteContext,
-    op: &ast::UnOp,
-    expr: &ast::Expr,
-    shape: Shape,
-) -> Option<String> {
-    // For some reason, an UnOp is not spanned like BinOp!
-    let operator_str = match *op {
-        ast::UnOp::Deref => "*",
-        ast::UnOp::Not => "!",
-        ast::UnOp::Neg => "-",
-    };
-    rewrite_unary_prefix(context, operator_str, expr, shape)
-}
-
-fn rewrite_assignment(
-    context: &RewriteContext,
-    lhs: &ast::Expr,
-    rhs: &ast::Expr,
-    op: Option<&ast::BinOp>,
-    shape: Shape,
-) -> Option<String> {
-    let operator_str = match op {
-        Some(op) => context.snippet(op.span),
-        None => "=",
-    };
-
-    // 1 = space between lhs and operator.
-    let lhs_shape = shape.sub_width(operator_str.len() + 1)?;
-    let lhs_str = format!("{} {}", lhs.rewrite(context, lhs_shape)?, operator_str);
-
-    rewrite_assign_rhs(context, lhs_str, rhs, shape)
-}
-
-// The left hand side must contain everything up to, and including, the
-// assignment operator.
-pub fn rewrite_assign_rhs<S: Into<String>, R: Rewrite>(
-    context: &RewriteContext,
-    lhs: S,
-    ex: &R,
-    shape: Shape,
-) -> Option<String> {
-    let lhs = lhs.into();
-    let last_line_width = last_line_width(&lhs)
-        .checked_sub(if lhs.contains('\n') {
-            shape.indent.width()
-        } else {
-            0
-        })
-        .unwrap_or(0);
-    // 1 = space between operator and rhs.
-    let orig_shape = shape.offset_left(last_line_width + 1).unwrap_or(Shape {
-        width: 0,
-        offset: shape.offset + last_line_width + 1,
-        ..shape
-    });
-    let rhs = choose_rhs(context, ex, orig_shape, ex.rewrite(context, orig_shape))?;
-    Some(lhs + &rhs)
-}
-
-pub fn choose_rhs<R: Rewrite>(
-    context: &RewriteContext,
-    expr: &R,
-    shape: Shape,
-    orig_rhs: Option<String>,
-) -> Option<String> {
-    match orig_rhs {
-        Some(ref new_str) if !new_str.contains('\n') && new_str.len() <= shape.width => {
-            Some(format!(" {}", new_str))
-        }
-        _ => {
-            // Expression did not fit on the same line as the identifier.
-            // Try splitting the line and see if that works better.
-            let new_shape =
-                Shape::indented(shape.indent.block_indent(context.config), context.config)
-                    .sub_width(shape.rhs_overhead(context.config))?;
-            let new_rhs = expr.rewrite(context, new_shape);
-            let new_indent_str = &new_shape.indent.to_string(context.config);
-
-            match (orig_rhs, new_rhs) {
-                (Some(ref orig_rhs), Some(ref new_rhs))
-                    if wrap_str(new_rhs.clone(), context.config.max_width(), new_shape)
-                        .is_none() =>
-                {
-                    Some(format!(" {}", orig_rhs))
-                }
-                (Some(ref orig_rhs), Some(ref new_rhs)) if prefer_next_line(orig_rhs, new_rhs) => {
-                    Some(format!("\n{}{}", new_indent_str, new_rhs))
-                }
-                (None, Some(ref new_rhs)) => Some(format!("\n{}{}", new_indent_str, new_rhs)),
-                (None, None) => None,
-                (Some(ref orig_rhs), _) => Some(format!(" {}", orig_rhs)),
-            }
-        }
-    }
-}
-
-fn prefer_next_line(orig_rhs: &str, next_line_rhs: &str) -> bool {
-    !next_line_rhs.contains('\n') || count_newlines(orig_rhs) > count_newlines(next_line_rhs) + 1
-}
-
-fn rewrite_expr_addrof(
-    context: &RewriteContext,
-    mutability: ast::Mutability,
-    expr: &ast::Expr,
-    shape: Shape,
-) -> Option<String> {
-    let operator_str = match mutability {
-        ast::Mutability::Immutable => "&",
-        ast::Mutability::Mutable => "&mut ",
-    };
-    rewrite_unary_prefix(context, operator_str, expr, shape)
-}
-
-pub trait ToExpr {
-    fn to_expr(&self) -> Option<&ast::Expr>;
-    fn can_be_overflowed(&self, context: &RewriteContext, len: usize) -> bool;
-}
-
-impl ToExpr for ast::Expr {
-    fn to_expr(&self) -> Option<&ast::Expr> {
-        Some(self)
-    }
-
-    fn can_be_overflowed(&self, context: &RewriteContext, len: usize) -> bool {
-        can_be_overflowed_expr(context, self, len)
-    }
-}
-
-impl ToExpr for ast::Ty {
-    fn to_expr(&self) -> Option<&ast::Expr> {
-        None
-    }
-
-    fn can_be_overflowed(&self, context: &RewriteContext, len: usize) -> bool {
-        can_be_overflowed_type(context, self, len)
-    }
-}
-
-impl<'a> ToExpr for TuplePatField<'a> {
-    fn to_expr(&self) -> Option<&ast::Expr> {
-        None
-    }
-
-    fn can_be_overflowed(&self, context: &RewriteContext, len: usize) -> bool {
-        can_be_overflowed_pat(context, self, len)
-    }
-}
-
-impl<'a> ToExpr for ast::StructField {
-    fn to_expr(&self) -> Option<&ast::Expr> {
-        None
-    }
-
-    fn can_be_overflowed(&self, _: &RewriteContext, _: usize) -> bool {
-        false
-    }
-}
-
-impl<'a> ToExpr for MacroArg {
-    fn to_expr(&self) -> Option<&ast::Expr> {
-        match *self {
-            MacroArg::Expr(ref expr) => Some(expr),
-            _ => None,
-        }
-    }
-
-    fn can_be_overflowed(&self, context: &RewriteContext, len: usize) -> bool {
-        match *self {
-            MacroArg::Expr(ref expr) => can_be_overflowed_expr(context, expr, len),
-            MacroArg::Ty(ref ty) => can_be_overflowed_type(context, ty, len),
-            MacroArg::Pat(..) => false,
-        }
-    }
-}
diff --git a/src/filemap.rs b/src/filemap.rs
deleted file mode 100644
index 81f950cfb9b..00000000000
--- a/src/filemap.rs
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// TODO: add tests
-
-use std::fs::{self, File};
-use std::io::{self, BufWriter, Read, Write};
-use std::path::Path;
-
-use checkstyle::{output_checkstyle_file, output_footer, output_header};
-use config::{Config, NewlineStyle, WriteMode};
-use rustfmt_diff::{make_diff, print_diff, Mismatch};
-use syntax::codemap::FileName;
-
-// A map of the files of a crate, with their new content
-pub type FileMap = Vec<FileRecord>;
-
-pub type FileRecord = (FileName, String);
-
-// Append a newline to the end of each file.
-pub fn append_newline(s: &mut String) {
-    s.push_str("\n");
-}
-
-pub fn write_all_files<T>(
-    file_map: &[FileRecord],
-    out: &mut T,
-    config: &Config,
-) -> Result<(), io::Error>
-where
-    T: Write,
-{
-    output_header(out, config.write_mode()).ok();
-    for &(ref filename, ref text) in file_map {
-        write_file(text, filename, out, config)?;
-    }
-    output_footer(out, config.write_mode()).ok();
-
-    Ok(())
-}
-
-// Prints all newlines either as `\n` or as `\r\n`.
-pub fn write_system_newlines<T>(writer: T, text: &str, config: &Config) -> Result<(), io::Error>
-where
-    T: Write,
-{
-    // Buffer output, since we're writing a since char at a time.
-    let mut writer = BufWriter::new(writer);
-
-    let style = if config.newline_style() == NewlineStyle::Native {
-        if cfg!(windows) {
-            NewlineStyle::Windows
-        } else {
-            NewlineStyle::Unix
-        }
-    } else {
-        config.newline_style()
-    };
-
-    match style {
-        NewlineStyle::Unix => write!(writer, "{}", text),
-        NewlineStyle::Windows => {
-            for c in text.chars() {
-                match c {
-                    '\n' => write!(writer, "\r\n")?,
-                    '\r' => continue,
-                    c => write!(writer, "{}", c)?,
-                }
-            }
-            Ok(())
-        }
-        NewlineStyle::Native => unreachable!(),
-    }
-}
-
-pub fn write_file<T>(
-    text: &str,
-    filename: &FileName,
-    out: &mut T,
-    config: &Config,
-) -> Result<bool, io::Error>
-where
-    T: Write,
-{
-    fn source_and_formatted_text(
-        text: &str,
-        filename: &Path,
-        config: &Config,
-    ) -> Result<(String, String), io::Error> {
-        let mut f = File::open(filename)?;
-        let mut ori_text = String::new();
-        f.read_to_string(&mut ori_text)?;
-        let mut v = Vec::new();
-        write_system_newlines(&mut v, text, config)?;
-        let fmt_text = String::from_utf8(v).unwrap();
-        Ok((ori_text, fmt_text))
-    }
-
-    fn create_diff(
-        filename: &Path,
-        text: &str,
-        config: &Config,
-    ) -> Result<Vec<Mismatch>, io::Error> {
-        let (ori, fmt) = source_and_formatted_text(text, filename, config)?;
-        Ok(make_diff(&ori, &fmt, 3))
-    }
-
-    let filename_to_path = || match *filename {
-        FileName::Real(ref path) => path,
-        _ => panic!("cannot format `{}` with WriteMode::Replace", filename),
-    };
-
-    match config.write_mode() {
-        WriteMode::Replace => {
-            let filename = filename_to_path();
-            if let Ok((ori, fmt)) = source_and_formatted_text(text, filename, config) {
-                if fmt != ori {
-                    // Do a little dance to make writing safer - write to a temp file
-                    // rename the original to a .bk, then rename the temp file to the
-                    // original.
-                    let tmp_name = filename.with_extension("tmp");
-                    let bk_name = filename.with_extension("bk");
-                    {
-                        // Write text to temp file
-                        let tmp_file = File::create(&tmp_name)?;
-                        write_system_newlines(tmp_file, text, config)?;
-                    }
-
-                    fs::rename(filename, bk_name)?;
-                    fs::rename(tmp_name, filename)?;
-                }
-            }
-        }
-        WriteMode::Overwrite => {
-            // Write text directly over original file if there is a diff.
-            let filename = filename_to_path();
-            let (source, formatted) = source_and_formatted_text(text, filename, config)?;
-            if source != formatted {
-                let file = File::create(filename)?;
-                write_system_newlines(file, text, config)?;
-            }
-        }
-        WriteMode::Plain => {
-            write_system_newlines(out, text, config)?;
-        }
-        WriteMode::Display | WriteMode::Coverage => {
-            println!("{}:\n", filename);
-            write_system_newlines(out, text, config)?;
-        }
-        WriteMode::Diff => {
-            let filename = filename_to_path();
-            if let Ok((ori, fmt)) = source_and_formatted_text(text, filename, config) {
-                let mismatch = make_diff(&ori, &fmt, 3);
-                let has_diff = !mismatch.is_empty();
-                print_diff(
-                    mismatch,
-                    |line_num| format!("Diff in {} at line {}:", filename.display(), line_num),
-                    config.color(),
-                );
-                return Ok(has_diff);
-            }
-        }
-        WriteMode::Checkstyle => {
-            let filename = filename_to_path();
-            let diff = create_diff(filename, text, config)?;
-            output_checkstyle_file(out, filename, diff)?;
-        }
-    }
-
-    // when we are not in diff mode, don't indicate differing files
-    Ok(false)
-}
diff --git a/src/imports.rs b/src/imports.rs
deleted file mode 100644
index 0b65cafe730..00000000000
--- a/src/imports.rs
+++ /dev/null
@@ -1,600 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::cmp::Ordering;
-
-use syntax::ast;
-use syntax::codemap::{BytePos, Span};
-
-use codemap::SpanUtils;
-use comment::combine_strs_with_missing_comments;
-use config::IndentStyle;
-use lists::{definitive_tactic, itemize_list, write_list, DefinitiveListTactic, ListFormatting,
-            ListItem, Separator, SeparatorPlace, SeparatorTactic};
-use rewrite::{Rewrite, RewriteContext};
-use shape::Shape;
-use spanned::Spanned;
-use types::{rewrite_path, PathContext};
-use utils::{format_visibility, mk_sp};
-use visitor::{rewrite_extern_crate, FmtVisitor};
-
-fn compare_path_segments(a: &ast::PathSegment, b: &ast::PathSegment) -> Ordering {
-    a.identifier.name.as_str().cmp(&b.identifier.name.as_str())
-}
-
-fn compare_paths(a: &ast::Path, b: &ast::Path) -> Ordering {
-    for segment in a.segments.iter().zip(b.segments.iter()) {
-        let ord = compare_path_segments(segment.0, segment.1);
-        if ord != Ordering::Equal {
-            return ord;
-        }
-    }
-    a.segments.len().cmp(&b.segments.len())
-}
-
-fn compare_use_trees(a: &ast::UseTree, b: &ast::UseTree, nested: bool) -> Ordering {
-    use ast::UseTreeKind::*;
-
-    // `use_nested_groups` is not yet supported, remove the `if !nested` when support will be
-    // fully added
-    if !nested {
-        let paths_cmp = compare_paths(&a.prefix, &b.prefix);
-        if paths_cmp != Ordering::Equal {
-            return paths_cmp;
-        }
-    }
-
-    match (&a.kind, &b.kind) {
-        (&Simple(ident_a), &Simple(ident_b)) => {
-            let name_a = &*path_to_imported_ident(&a.prefix).name.as_str();
-            let name_b = &*path_to_imported_ident(&b.prefix).name.as_str();
-            let name_ordering = if name_a == "self" {
-                if name_b == "self" {
-                    Ordering::Equal
-                } else {
-                    Ordering::Less
-                }
-            } else if name_b == "self" {
-                Ordering::Greater
-            } else {
-                name_a.cmp(name_b)
-            };
-            if name_ordering == Ordering::Equal {
-                if ident_a.name.as_str() != name_a {
-                    if ident_b.name.as_str() != name_b {
-                        ident_a.name.as_str().cmp(&ident_b.name.as_str())
-                    } else {
-                        Ordering::Greater
-                    }
-                } else {
-                    Ordering::Less
-                }
-            } else {
-                name_ordering
-            }
-        }
-        (&Glob, &Glob) => Ordering::Equal,
-        (&Simple(_), _) | (&Glob, &Nested(_)) => Ordering::Less,
-        (&Nested(ref a_items), &Nested(ref b_items)) => {
-            let mut a = a_items
-                .iter()
-                .map(|&(ref tree, _)| tree.clone())
-                .collect::<Vec<_>>();
-            let mut b = b_items
-                .iter()
-                .map(|&(ref tree, _)| tree.clone())
-                .collect::<Vec<_>>();
-            a.sort_by(|a, b| compare_use_trees(a, b, true));
-            b.sort_by(|a, b| compare_use_trees(a, b, true));
-            for comparison_pair in a.iter().zip(b.iter()) {
-                let ord = compare_use_trees(comparison_pair.0, comparison_pair.1, true);
-                if ord != Ordering::Equal {
-                    return ord;
-                }
-            }
-            a.len().cmp(&b.len())
-        }
-        (&Glob, &Simple(_)) | (&Nested(_), _) => Ordering::Greater,
-    }
-}
-
-fn compare_use_items(a: &ast::Item, b: &ast::Item) -> Ordering {
-    match (&a.node, &b.node) {
-        (&ast::ItemKind::Mod(..), &ast::ItemKind::Mod(..)) => {
-            a.ident.name.as_str().cmp(&b.ident.name.as_str())
-        }
-        (&ast::ItemKind::Use(ref a_tree), &ast::ItemKind::Use(ref b_tree)) => {
-            compare_use_trees(a_tree, b_tree, false)
-        }
-        (&ast::ItemKind::ExternCrate(ref a_name), &ast::ItemKind::ExternCrate(ref b_name)) => {
-            // `extern crate foo as bar;`
-            //               ^^^ Comparing this.
-            let a_orig_name =
-                a_name.map_or_else(|| a.ident.name.as_str(), |symbol| symbol.as_str());
-            let b_orig_name =
-                b_name.map_or_else(|| b.ident.name.as_str(), |symbol| symbol.as_str());
-            let result = a_orig_name.cmp(&b_orig_name);
-            if result != Ordering::Equal {
-                return result;
-            }
-
-            // `extern crate foo as bar;`
-            //                      ^^^ Comparing this.
-            match (a_name, b_name) {
-                (Some(..), None) => Ordering::Greater,
-                (None, Some(..)) => Ordering::Less,
-                (None, None) => Ordering::Equal,
-                (Some(..), Some(..)) => a.ident.name.as_str().cmp(&b.ident.name.as_str()),
-            }
-        }
-        _ => unreachable!(),
-    }
-}
-
-// TODO (some day) remove unused imports, expand globs, compress many single
-// imports into a list import.
-
-fn rewrite_prefix(path: &ast::Path, context: &RewriteContext, shape: Shape) -> Option<String> {
-    if path.segments.len() > 1 && path_to_imported_ident(path).to_string() == "self" {
-        let path = &ast::Path {
-            span: path.span,
-            segments: path.segments[..path.segments.len() - 1].to_owned(),
-        };
-        rewrite_path(context, PathContext::Import, None, path, shape)
-    } else {
-        rewrite_path(context, PathContext::Import, None, path, shape)
-    }
-}
-
-impl Rewrite for ast::UseTree {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        match self.kind {
-            ast::UseTreeKind::Nested(ref items) => {
-                rewrite_nested_use_tree(shape, &self.prefix, items, self.span, context)
-            }
-            ast::UseTreeKind::Glob => {
-                let prefix_shape = shape.sub_width(3)?;
-
-                if !self.prefix.segments.is_empty() {
-                    let path_str = rewrite_prefix(&self.prefix, context, prefix_shape)?;
-                    Some(format!("{}::*", path_str))
-                } else {
-                    Some("*".to_owned())
-                }
-            }
-            ast::UseTreeKind::Simple(ident) => {
-                let ident_str = ident.to_string();
-
-                // 4 = " as ".len()
-                let is_same_name_bind = path_to_imported_ident(&self.prefix) == ident;
-                let prefix_shape = if is_same_name_bind {
-                    shape
-                } else {
-                    shape.sub_width(ident_str.len() + 4)?
-                };
-                let path_str = rewrite_prefix(&self.prefix, context, prefix_shape)
-                    .unwrap_or_else(|| context.snippet(self.prefix.span).to_owned());
-
-                if is_same_name_bind {
-                    Some(path_str)
-                } else {
-                    Some(format!("{} as {}", path_str, ident_str))
-                }
-            }
-        }
-    }
-}
-
-fn is_unused_import(tree: &ast::UseTree, attrs: &[ast::Attribute]) -> bool {
-    attrs.is_empty() && is_unused_import_inner(tree)
-}
-
-fn is_unused_import_inner(tree: &ast::UseTree) -> bool {
-    match tree.kind {
-        ast::UseTreeKind::Nested(ref items) => match items.len() {
-            0 => true,
-            1 => is_unused_import_inner(&items[0].0),
-            _ => false,
-        },
-        _ => false,
-    }
-}
-
-// Rewrite `use foo;` WITHOUT attributes.
-fn rewrite_import(
-    context: &RewriteContext,
-    vis: &ast::Visibility,
-    tree: &ast::UseTree,
-    attrs: &[ast::Attribute],
-    shape: Shape,
-) -> Option<String> {
-    let vis = format_visibility(vis);
-    // 4 = `use `, 1 = `;`
-    let rw = shape
-        .offset_left(vis.len() + 4)
-        .and_then(|shape| shape.sub_width(1))
-        .and_then(|shape| {
-            // If we have an empty nested group with no attributes, we erase it
-            if is_unused_import(tree, attrs) {
-                Some("".to_owned())
-            } else {
-                tree.rewrite(context, shape)
-            }
-        });
-    match rw {
-        Some(ref s) if !s.is_empty() => Some(format!("{}use {};", vis, s)),
-        _ => rw,
-    }
-}
-
-/// Rewrite an inline mod.
-fn rewrite_mod(item: &ast::Item) -> String {
-    let mut result = String::with_capacity(32);
-    result.push_str(&*format_visibility(&item.vis));
-    result.push_str("mod ");
-    result.push_str(&item.ident.to_string());
-    result.push(';');
-    result
-}
-
-fn rewrite_imports(
-    context: &RewriteContext,
-    use_items: &[&ast::Item],
-    shape: Shape,
-    span: Span,
-) -> Option<String> {
-    let items = itemize_list(
-        context.codemap,
-        use_items.iter(),
-        "",
-        ";",
-        |item| item.span().lo(),
-        |item| item.span().hi(),
-        |item| {
-            let attrs = ::visitor::filter_inline_attrs(&item.attrs, item.span());
-            let attrs_str = attrs.rewrite(context, shape)?;
-
-            let missed_span = if attrs.is_empty() {
-                mk_sp(item.span.lo(), item.span.lo())
-            } else {
-                mk_sp(attrs.last().unwrap().span.hi(), item.span.lo())
-            };
-
-            let item_str = match item.node {
-                ast::ItemKind::Use(ref tree) => {
-                    rewrite_import(context, &item.vis, tree, &item.attrs, shape)?
-                }
-                ast::ItemKind::ExternCrate(..) => rewrite_extern_crate(context, item)?,
-                ast::ItemKind::Mod(..) => rewrite_mod(item),
-                _ => return None,
-            };
-
-            combine_strs_with_missing_comments(
-                context,
-                &attrs_str,
-                &item_str,
-                missed_span,
-                shape,
-                false,
-            )
-        },
-        span.lo(),
-        span.hi(),
-        false,
-    );
-    let mut item_pair_vec: Vec<_> = items.zip(use_items.iter()).collect();
-    item_pair_vec.sort_by(|a, b| compare_use_items(a.1, b.1));
-    let item_vec: Vec<_> = item_pair_vec.into_iter().map(|pair| pair.0).collect();
-
-    let fmt = ListFormatting {
-        tactic: DefinitiveListTactic::Vertical,
-        separator: "",
-        trailing_separator: SeparatorTactic::Never,
-        separator_place: SeparatorPlace::Back,
-        shape,
-        ends_with_newline: true,
-        preserve_newline: false,
-        config: context.config,
-    };
-
-    write_list(&item_vec, &fmt)
-}
-
-impl<'a> FmtVisitor<'a> {
-    pub fn format_imports(&mut self, use_items: &[&ast::Item]) {
-        if use_items.is_empty() {
-            return;
-        }
-
-        let lo = use_items.first().unwrap().span().lo();
-        let hi = use_items.last().unwrap().span().hi();
-        let span = mk_sp(lo, hi);
-        let rw = rewrite_imports(&self.get_context(), use_items, self.shape(), span);
-        self.push_rewrite(span, rw);
-    }
-
-    pub fn format_import(&mut self, item: &ast::Item, tree: &ast::UseTree) {
-        let span = item.span;
-        let shape = self.shape();
-        let rw = rewrite_import(&self.get_context(), &item.vis, tree, &item.attrs, shape);
-        match rw {
-            Some(ref s) if s.is_empty() => {
-                // Format up to last newline
-                let prev_span = mk_sp(self.last_pos, source!(self, span).lo());
-                let trimmed_snippet = self.snippet(prev_span).trim_right();
-                let span_end = self.last_pos + BytePos(trimmed_snippet.len() as u32);
-                self.format_missing(span_end);
-                // We have an excessive newline from the removed import.
-                if self.buffer.ends_with('\n') {
-                    self.buffer.pop();
-                    self.line_number -= 1;
-                }
-                self.last_pos = source!(self, span).hi();
-            }
-            Some(ref s) => {
-                self.format_missing_with_indent(source!(self, span).lo());
-                self.push_str(s);
-                self.last_pos = source!(self, span).hi();
-            }
-            None => {
-                self.format_missing_with_indent(source!(self, span).lo());
-                self.format_missing(source!(self, span).hi());
-            }
-        }
-    }
-}
-
-fn rewrite_nested_use_tree_single(
-    context: &RewriteContext,
-    path_str: &str,
-    tree: &ast::UseTree,
-    shape: Shape,
-) -> Option<String> {
-    match tree.kind {
-        ast::UseTreeKind::Simple(rename) => {
-            let ident = path_to_imported_ident(&tree.prefix);
-            let mut item_str = rewrite_prefix(&tree.prefix, context, shape)?;
-            if item_str == "self" {
-                item_str = "".to_owned();
-            }
-
-            let path_item_str = if path_str.is_empty() {
-                if item_str.is_empty() {
-                    "self".to_owned()
-                } else {
-                    item_str
-                }
-            } else if item_str.is_empty() {
-                path_str.to_owned()
-            } else {
-                format!("{}::{}", path_str, item_str)
-            };
-
-            Some(if ident == rename {
-                path_item_str
-            } else {
-                format!("{} as {}", path_item_str, rename)
-            })
-        }
-        ast::UseTreeKind::Glob | ast::UseTreeKind::Nested(..) => {
-            // 2 = "::"
-            let nested_shape = shape.offset_left(path_str.len() + 2)?;
-            tree.rewrite(context, nested_shape)
-                .map(|item| format!("{}::{}", path_str, item))
-        }
-    }
-}
-
-#[derive(Eq, PartialEq)]
-enum ImportItem<'a> {
-    // `self` or `self as a`
-    SelfImport(&'a str),
-    // name_one, name_two, ...
-    SnakeCase(&'a str),
-    // NameOne, NameTwo, ...
-    CamelCase(&'a str),
-    // NAME_ONE, NAME_TWO, ...
-    AllCaps(&'a str),
-    // Failed to format the import item
-    Invalid,
-}
-
-impl<'a> ImportItem<'a> {
-    fn from_str(s: &str) -> ImportItem {
-        if s == "self" || s.starts_with("self as") {
-            ImportItem::SelfImport(s)
-        } else if s.chars().all(|c| c.is_lowercase() || c == '_' || c == ' ') {
-            ImportItem::SnakeCase(s)
-        } else if s.chars().all(|c| c.is_uppercase() || c == '_' || c == ' ') {
-            ImportItem::AllCaps(s)
-        } else {
-            ImportItem::CamelCase(s)
-        }
-    }
-
-    fn from_opt_str(s: Option<&String>) -> ImportItem {
-        s.map_or(ImportItem::Invalid, |s| ImportItem::from_str(s))
-    }
-
-    fn to_str(&self) -> Option<&str> {
-        match *self {
-            ImportItem::SelfImport(s)
-            | ImportItem::SnakeCase(s)
-            | ImportItem::CamelCase(s)
-            | ImportItem::AllCaps(s) => Some(s),
-            ImportItem::Invalid => None,
-        }
-    }
-
-    fn to_u32(&self) -> u32 {
-        match *self {
-            ImportItem::SelfImport(..) => 0,
-            ImportItem::SnakeCase(..) => 1,
-            ImportItem::CamelCase(..) => 2,
-            ImportItem::AllCaps(..) => 3,
-            ImportItem::Invalid => 4,
-        }
-    }
-}
-
-impl<'a> PartialOrd for ImportItem<'a> {
-    fn partial_cmp(&self, other: &ImportItem<'a>) -> Option<Ordering> {
-        Some(self.cmp(other))
-    }
-}
-
-impl<'a> Ord for ImportItem<'a> {
-    fn cmp(&self, other: &ImportItem<'a>) -> Ordering {
-        let res = self.to_u32().cmp(&other.to_u32());
-        if res != Ordering::Equal {
-            return res;
-        }
-        self.to_str().map_or(Ordering::Greater, |self_str| {
-            other
-                .to_str()
-                .map_or(Ordering::Less, |other_str| self_str.cmp(other_str))
-        })
-    }
-}
-
-// Pretty prints a multi-item import.
-// If the path list is empty, it leaves the braces empty.
-fn rewrite_nested_use_tree(
-    shape: Shape,
-    path: &ast::Path,
-    trees: &[(ast::UseTree, ast::NodeId)],
-    span: Span,
-    context: &RewriteContext,
-) -> Option<String> {
-    // Returns a different option to distinguish `::foo` and `foo`
-    let path_str = rewrite_path(context, PathContext::Import, None, path, shape)?;
-
-    match trees.len() {
-        0 => {
-            let shape = shape.offset_left(path_str.len() + 3)?;
-            return rewrite_path(context, PathContext::Import, None, path, shape)
-                .map(|path_str| format!("{}::{{}}", path_str));
-        }
-        1 => {
-            return rewrite_nested_use_tree_single(context, &path_str, &trees[0].0, shape);
-        }
-        _ => (),
-    }
-
-    let path_str = if path_str.is_empty() {
-        path_str
-    } else {
-        format!("{}::", path_str)
-    };
-
-    // 2 = "{}"
-    let remaining_width = shape.width.checked_sub(path_str.len() + 2).unwrap_or(0);
-    let nested_indent = match context.config.imports_indent() {
-        IndentStyle::Block => shape.indent.block_indent(context.config),
-        // 1 = `{`
-        IndentStyle::Visual => shape.visual_indent(path_str.len() + 1).indent,
-    };
-
-    let nested_shape = match context.config.imports_indent() {
-        IndentStyle::Block => Shape::indented(nested_indent, context.config).sub_width(1)?,
-        IndentStyle::Visual => Shape::legacy(remaining_width, nested_indent),
-    };
-
-    let mut items = {
-        // Dummy value, see explanation below.
-        let mut items = vec![ListItem::from_str("")];
-        let iter = itemize_list(
-            context.codemap,
-            trees.iter().map(|tree| &tree.0),
-            "}",
-            ",",
-            |tree| tree.span.lo(),
-            |tree| tree.span.hi(),
-            |tree| tree.rewrite(context, nested_shape),
-            context.codemap.span_after(span, "{"),
-            span.hi(),
-            false,
-        );
-        items.extend(iter);
-        items
-    };
-
-    // We prefixed the item list with a dummy value so that we can
-    // potentially move "self" to the front of the vector without touching
-    // the rest of the items.
-    let has_self = move_self_to_front(&mut items);
-    let first_index = if has_self { 0 } else { 1 };
-
-    if context.config.reorder_imported_names() {
-        items[1..].sort_by(|a, b| {
-            let a = ImportItem::from_opt_str(a.item.as_ref());
-            let b = ImportItem::from_opt_str(b.item.as_ref());
-            a.cmp(&b)
-        });
-    }
-
-    let tactic = definitive_tactic(
-        &items[first_index..],
-        context.config.imports_layout(),
-        Separator::Comma,
-        remaining_width,
-    );
-
-    let ends_with_newline = context.config.imports_indent() == IndentStyle::Block
-        && tactic != DefinitiveListTactic::Horizontal;
-
-    let fmt = ListFormatting {
-        tactic,
-        separator: ",",
-        trailing_separator: if ends_with_newline {
-            context.config.trailing_comma()
-        } else {
-            SeparatorTactic::Never
-        },
-        separator_place: SeparatorPlace::Back,
-        shape: nested_shape,
-        ends_with_newline,
-        preserve_newline: true,
-        config: context.config,
-    };
-    let list_str = write_list(&items[first_index..], &fmt)?;
-
-    let result = if list_str.contains('\n') && context.config.imports_indent() == IndentStyle::Block
-    {
-        format!(
-            "{}{{\n{}{}\n{}}}",
-            path_str,
-            nested_shape.indent.to_string(context.config),
-            list_str,
-            shape.indent.to_string(context.config)
-        )
-    } else {
-        format!("{}{{{}}}", path_str, list_str)
-    };
-    Some(result)
-}
-
-// Returns true when self item was found.
-fn move_self_to_front(items: &mut Vec<ListItem>) -> bool {
-    match items
-        .iter()
-        .position(|item| item.item.as_ref().map(|x| &x[..]) == Some("self"))
-    {
-        Some(pos) => {
-            items[0] = items.remove(pos);
-            true
-        }
-        None => false,
-    }
-}
-
-fn path_to_imported_ident(path: &ast::Path) -> ast::Ident {
-    path.segments.last().unwrap().identifier
-}
diff --git a/src/issues.rs b/src/issues.rs
deleted file mode 100644
index 2efd61a3d7d..00000000000
--- a/src/issues.rs
+++ /dev/null
@@ -1,325 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Objects for seeking through a char stream for occurrences of TODO and FIXME.
-// Depending on the loaded configuration, may also check that these have an
-// associated issue number.
-
-use std::fmt;
-
-pub use config::ReportTactic;
-
-const TO_DO_CHARS: &[char] = &['t', 'o', 'd', 'o'];
-const FIX_ME_CHARS: &[char] = &['f', 'i', 'x', 'm', 'e'];
-
-// Enabled implementation detail is here because it is
-// irrelevant outside the issues module
-impl ReportTactic {
-    fn is_enabled(&self) -> bool {
-        *self != ReportTactic::Never
-    }
-}
-
-#[derive(Clone, Copy)]
-enum Seeking {
-    Issue { todo_idx: usize, fixme_idx: usize },
-    Number { issue: Issue, part: NumberPart },
-}
-
-#[derive(Clone, Copy)]
-enum NumberPart {
-    OpenParen,
-    Pound,
-    Number,
-    CloseParen,
-}
-
-#[derive(PartialEq, Eq, Debug, Clone, Copy)]
-pub struct Issue {
-    issue_type: IssueType,
-    // Indicates whether we're looking for issues with missing numbers, or
-    // all issues of this type.
-    missing_number: bool,
-}
-
-impl fmt::Display for Issue {
-    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-        let msg = match self.issue_type {
-            IssueType::Todo => "TODO",
-            IssueType::Fixme => "FIXME",
-        };
-        let details = if self.missing_number {
-            " without issue number"
-        } else {
-            ""
-        };
-
-        write!(fmt, "{}{}", msg, details)
-    }
-}
-
-#[derive(PartialEq, Eq, Debug, Clone, Copy)]
-enum IssueType {
-    Todo,
-    Fixme,
-}
-
-enum IssueClassification {
-    Good,
-    Bad(Issue),
-    None,
-}
-
-pub struct BadIssueSeeker {
-    state: Seeking,
-    report_todo: ReportTactic,
-    report_fixme: ReportTactic,
-}
-
-impl BadIssueSeeker {
-    pub fn new(report_todo: ReportTactic, report_fixme: ReportTactic) -> BadIssueSeeker {
-        BadIssueSeeker {
-            state: Seeking::Issue {
-                todo_idx: 0,
-                fixme_idx: 0,
-            },
-            report_todo,
-            report_fixme,
-        }
-    }
-
-    // Check whether or not the current char is conclusive evidence for an
-    // unnumbered TO-DO or FIX-ME.
-    pub fn inspect(&mut self, c: char) -> Option<Issue> {
-        match self.state {
-            Seeking::Issue {
-                todo_idx,
-                fixme_idx,
-            } => {
-                self.state = self.inspect_issue(c, todo_idx, fixme_idx);
-            }
-            Seeking::Number { issue, part } => {
-                let result = self.inspect_number(c, issue, part);
-
-                if let IssueClassification::None = result {
-                    return None;
-                }
-
-                self.state = Seeking::Issue {
-                    todo_idx: 0,
-                    fixme_idx: 0,
-                };
-
-                if let IssueClassification::Bad(issue) = result {
-                    return Some(issue);
-                }
-            }
-        }
-
-        None
-    }
-
-    fn inspect_issue(&mut self, c: char, mut todo_idx: usize, mut fixme_idx: usize) -> Seeking {
-        if let Some(lower_case_c) = c.to_lowercase().next() {
-            if self.report_todo.is_enabled() && lower_case_c == TO_DO_CHARS[todo_idx] {
-                todo_idx += 1;
-                if todo_idx == TO_DO_CHARS.len() {
-                    return Seeking::Number {
-                        issue: Issue {
-                            issue_type: IssueType::Todo,
-                            missing_number: if let ReportTactic::Unnumbered = self.report_todo {
-                                true
-                            } else {
-                                false
-                            },
-                        },
-                        part: NumberPart::OpenParen,
-                    };
-                }
-                fixme_idx = 0;
-            } else if self.report_fixme.is_enabled() && lower_case_c == FIX_ME_CHARS[fixme_idx] {
-                // Exploit the fact that the character sets of todo and fixme
-                // are disjoint by adding else.
-                fixme_idx += 1;
-                if fixme_idx == FIX_ME_CHARS.len() {
-                    return Seeking::Number {
-                        issue: Issue {
-                            issue_type: IssueType::Fixme,
-                            missing_number: if let ReportTactic::Unnumbered = self.report_fixme {
-                                true
-                            } else {
-                                false
-                            },
-                        },
-                        part: NumberPart::OpenParen,
-                    };
-                }
-                todo_idx = 0;
-            } else {
-                todo_idx = 0;
-                fixme_idx = 0;
-            }
-        }
-
-        Seeking::Issue {
-            todo_idx,
-            fixme_idx,
-        }
-    }
-
-    fn inspect_number(
-        &mut self,
-        c: char,
-        issue: Issue,
-        mut part: NumberPart,
-    ) -> IssueClassification {
-        if !issue.missing_number || c == '\n' {
-            return IssueClassification::Bad(issue);
-        } else if c == ')' {
-            return if let NumberPart::CloseParen = part {
-                IssueClassification::Good
-            } else {
-                IssueClassification::Bad(issue)
-            };
-        }
-
-        match part {
-            NumberPart::OpenParen => {
-                if c != '(' {
-                    return IssueClassification::Bad(issue);
-                } else {
-                    part = NumberPart::Pound;
-                }
-            }
-            NumberPart::Pound => {
-                if c == '#' {
-                    part = NumberPart::Number;
-                }
-            }
-            NumberPart::Number => {
-                if c >= '0' && c <= '9' {
-                    part = NumberPart::CloseParen;
-                } else {
-                    return IssueClassification::Bad(issue);
-                }
-            }
-            NumberPart::CloseParen => {}
-        }
-
-        self.state = Seeking::Number { part, issue };
-
-        IssueClassification::None
-    }
-}
-
-#[test]
-fn find_unnumbered_issue() {
-    fn check_fail(text: &str, failing_pos: usize) {
-        let mut seeker = BadIssueSeeker::new(ReportTactic::Unnumbered, ReportTactic::Unnumbered);
-        assert_eq!(
-            Some(failing_pos),
-            text.chars().position(|c| seeker.inspect(c).is_some())
-        );
-    }
-
-    fn check_pass(text: &str) {
-        let mut seeker = BadIssueSeeker::new(ReportTactic::Unnumbered, ReportTactic::Unnumbered);
-        assert_eq!(None, text.chars().position(|c| seeker.inspect(c).is_some()));
-    }
-
-    check_fail("TODO\n", 4);
-    check_pass(" TO FIX DOME\n");
-    check_fail(" \n FIXME\n", 8);
-    check_fail("FIXME(\n", 6);
-    check_fail("FIXME(#\n", 7);
-    check_fail("FIXME(#1\n", 8);
-    check_fail("FIXME(#)1\n", 7);
-    check_pass("FIXME(#1222)\n");
-    check_fail("FIXME(#12\n22)\n", 9);
-    check_pass("FIXME(@maintainer, #1222, hello)\n");
-    check_fail("TODO(#22) FIXME\n", 15);
-}
-
-#[test]
-fn find_issue() {
-    fn is_bad_issue(text: &str, report_todo: ReportTactic, report_fixme: ReportTactic) -> bool {
-        let mut seeker = BadIssueSeeker::new(report_todo, report_fixme);
-        text.chars().any(|c| seeker.inspect(c).is_some())
-    }
-
-    assert!(is_bad_issue(
-        "TODO(@maintainer, #1222, hello)\n",
-        ReportTactic::Always,
-        ReportTactic::Never,
-    ));
-
-    assert!(!is_bad_issue(
-        "TODO: no number\n",
-        ReportTactic::Never,
-        ReportTactic::Always,
-    ));
-
-    assert!(!is_bad_issue(
-        "Todo: mixed case\n",
-        ReportTactic::Never,
-        ReportTactic::Always,
-    ));
-
-    assert!(is_bad_issue(
-        "This is a FIXME(#1)\n",
-        ReportTactic::Never,
-        ReportTactic::Always,
-    ));
-
-    assert!(is_bad_issue(
-        "This is a FixMe(#1) mixed case\n",
-        ReportTactic::Never,
-        ReportTactic::Always,
-    ));
-
-    assert!(!is_bad_issue(
-        "bad FIXME\n",
-        ReportTactic::Always,
-        ReportTactic::Never,
-    ));
-}
-
-#[test]
-fn issue_type() {
-    let mut seeker = BadIssueSeeker::new(ReportTactic::Always, ReportTactic::Never);
-    let expected = Some(Issue {
-        issue_type: IssueType::Todo,
-        missing_number: false,
-    });
-
-    assert_eq!(
-        expected,
-        "TODO(#100): more awesomeness"
-            .chars()
-            .map(|c| seeker.inspect(c))
-            .find(Option::is_some)
-            .unwrap()
-    );
-
-    let mut seeker = BadIssueSeeker::new(ReportTactic::Never, ReportTactic::Unnumbered);
-    let expected = Some(Issue {
-        issue_type: IssueType::Fixme,
-        missing_number: true,
-    });
-
-    assert_eq!(
-        expected,
-        "Test. FIXME: bad, bad, not good"
-            .chars()
-            .map(|c| seeker.inspect(c))
-            .find(Option::is_some)
-            .unwrap()
-    );
-}
diff --git a/src/items.rs b/src/items.rs
deleted file mode 100644
index 510c96681b8..00000000000
--- a/src/items.rs
+++ /dev/null
@@ -1,2845 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Formatting top-level items - functions, structs, enums, traits, impls.
-
-use std::borrow::Cow;
-use std::cmp::min;
-
-use syntax::{abi, ast, ptr, symbol};
-use syntax::ast::{CrateSugar, ImplItem};
-use syntax::codemap::{BytePos, Span};
-use syntax::visit;
-
-use codemap::{LineRangeUtils, SpanUtils};
-use comment::{combine_strs_with_missing_comments, contains_comment, recover_comment_removed,
-              recover_missing_comment_in_span, rewrite_missing_comment, FindUncommented};
-use config::{BraceStyle, Config, Density, IndentStyle};
-use expr::{format_expr, is_empty_block, is_simple_block_stmt, rewrite_assign_rhs,
-           rewrite_call_inner, ExprType};
-use lists::{definitive_tactic, itemize_list, write_list, DefinitiveListTactic, ListFormatting,
-            ListItem, ListTactic, Separator, SeparatorPlace, SeparatorTactic};
-use rewrite::{Rewrite, RewriteContext};
-use shape::{Indent, Shape};
-use spanned::Spanned;
-use types::join_bounds;
-use utils::{colon_spaces, contains_skip, first_line_width, format_abi, format_constness,
-            format_defaultness, format_mutability, format_unsafety, format_visibility,
-            is_attributes_extendable, last_line_contains_single_line_comment,
-            last_line_extendable, last_line_used_width, last_line_width, mk_sp,
-            semicolon_for_expr, starts_with_newline, stmt_expr, trimmed_last_line_width};
-use vertical::rewrite_with_alignment;
-use visitor::FmtVisitor;
-
-fn type_annotation_separator(config: &Config) -> &str {
-    colon_spaces(config.space_before_colon(), config.space_after_colon())
-}
-
-// Statements of the form
-// let pat: ty = init;
-impl Rewrite for ast::Local {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        debug!(
-            "Local::rewrite {:?} {} {:?}",
-            self, shape.width, shape.indent
-        );
-
-        skip_out_of_file_lines_range!(context, self.span);
-
-        if contains_skip(&self.attrs) {
-            return None;
-        }
-
-        let attrs_str = self.attrs.rewrite(context, shape)?;
-        let mut result = if attrs_str.is_empty() {
-            "let ".to_owned()
-        } else {
-            combine_strs_with_missing_comments(
-                context,
-                &attrs_str,
-                "let ",
-                mk_sp(
-                    self.attrs.last().map(|a| a.span.hi()).unwrap(),
-                    self.span.lo(),
-                ),
-                shape,
-                false,
-            )?
-        };
-
-        // 4 = "let ".len()
-        let pat_shape = shape.offset_left(4)?;
-        // 1 = ;
-        let pat_shape = pat_shape.sub_width(1)?;
-        let pat_str = self.pat.rewrite(context, pat_shape)?;
-        result.push_str(&pat_str);
-
-        // String that is placed within the assignment pattern and expression.
-        let infix = {
-            let mut infix = String::with_capacity(32);
-
-            if let Some(ref ty) = self.ty {
-                let separator = type_annotation_separator(context.config);
-                let indent = shape.indent + last_line_width(&result) + separator.len();
-                // 1 = ;
-                let budget = shape.width.checked_sub(indent.width() + 1)?;
-                let rewrite = ty.rewrite(context, Shape::legacy(budget, indent))?;
-
-                infix.push_str(separator);
-                infix.push_str(&rewrite);
-            }
-
-            if self.init.is_some() {
-                infix.push_str(" =");
-            }
-
-            infix
-        };
-
-        result.push_str(&infix);
-
-        if let Some(ref ex) = self.init {
-            // 1 = trailing semicolon;
-            let nested_shape = shape.sub_width(1)?;
-
-            result = rewrite_assign_rhs(context, result, &**ex, nested_shape)?;
-        }
-
-        result.push(';');
-        Some(result)
-    }
-}
-
-// TODO convert to using rewrite style rather than visitor
-// TODO format modules in this style
-#[allow(dead_code)]
-struct Item<'a> {
-    keyword: &'static str,
-    abi: Cow<'static, str>,
-    vis: Option<&'a ast::Visibility>,
-    body: Vec<BodyElement<'a>>,
-    span: Span,
-}
-
-impl<'a> Item<'a> {
-    fn from_foreign_mod(fm: &'a ast::ForeignMod, span: Span, config: &Config) -> Item<'a> {
-        Item {
-            keyword: "",
-            abi: format_abi(fm.abi, config.force_explicit_abi(), true),
-            vis: None,
-            body: fm.items
-                .iter()
-                .map(|i| BodyElement::ForeignItem(i))
-                .collect(),
-            span,
-        }
-    }
-}
-
-enum BodyElement<'a> {
-    // Stmt(&'a ast::Stmt),
-    // Field(&'a ast::Field),
-    // Variant(&'a ast::Variant),
-    // Item(&'a ast::Item),
-    ForeignItem(&'a ast::ForeignItem),
-}
-
-/// Represents a fn's signature.
-pub struct FnSig<'a> {
-    decl: &'a ast::FnDecl,
-    generics: &'a ast::Generics,
-    abi: abi::Abi,
-    constness: ast::Constness,
-    defaultness: ast::Defaultness,
-    unsafety: ast::Unsafety,
-    visibility: ast::Visibility,
-}
-
-impl<'a> FnSig<'a> {
-    pub fn new(
-        decl: &'a ast::FnDecl,
-        generics: &'a ast::Generics,
-        vis: ast::Visibility,
-    ) -> FnSig<'a> {
-        FnSig {
-            decl,
-            generics,
-            abi: abi::Abi::Rust,
-            constness: ast::Constness::NotConst,
-            defaultness: ast::Defaultness::Final,
-            unsafety: ast::Unsafety::Normal,
-            visibility: vis,
-        }
-    }
-
-    pub fn from_method_sig(
-        method_sig: &'a ast::MethodSig,
-        generics: &'a ast::Generics,
-    ) -> FnSig<'a> {
-        FnSig {
-            unsafety: method_sig.unsafety,
-            constness: method_sig.constness.node,
-            defaultness: ast::Defaultness::Final,
-            abi: method_sig.abi,
-            decl: &*method_sig.decl,
-            generics,
-            visibility: ast::Visibility::Inherited,
-        }
-    }
-
-    pub fn from_fn_kind(
-        fn_kind: &'a visit::FnKind,
-        generics: &'a ast::Generics,
-        decl: &'a ast::FnDecl,
-        defualtness: ast::Defaultness,
-    ) -> FnSig<'a> {
-        match *fn_kind {
-            visit::FnKind::ItemFn(_, unsafety, constness, abi, visibility, _) => FnSig {
-                decl,
-                generics,
-                abi,
-                constness: constness.node,
-                defaultness: defualtness,
-                unsafety,
-                visibility: visibility.clone(),
-            },
-            visit::FnKind::Method(_, method_sig, vis, _) => {
-                let mut fn_sig = FnSig::from_method_sig(method_sig, generics);
-                fn_sig.defaultness = defualtness;
-                if let Some(vis) = vis {
-                    fn_sig.visibility = vis.clone();
-                }
-                fn_sig
-            }
-            _ => unreachable!(),
-        }
-    }
-
-    fn to_str(&self, context: &RewriteContext) -> String {
-        let mut result = String::with_capacity(128);
-        // Vis defaultness constness unsafety abi.
-        result.push_str(&*format_visibility(&self.visibility));
-        result.push_str(format_defaultness(self.defaultness));
-        result.push_str(format_constness(self.constness));
-        result.push_str(format_unsafety(self.unsafety));
-        result.push_str(&format_abi(
-            self.abi,
-            context.config.force_explicit_abi(),
-            false,
-        ));
-        result
-    }
-}
-
-impl<'a> FmtVisitor<'a> {
-    fn format_item(&mut self, item: &Item) {
-        self.buffer.push_str(&item.abi);
-
-        let snippet = self.snippet(item.span);
-        let brace_pos = snippet.find_uncommented("{").unwrap();
-
-        self.push_str("{");
-        if !item.body.is_empty() || contains_comment(&snippet[brace_pos..]) {
-            // FIXME: this skips comments between the extern keyword and the opening
-            // brace.
-            self.last_pos = item.span.lo() + BytePos(brace_pos as u32 + 1);
-            self.block_indent = self.block_indent.block_indent(self.config);
-
-            if item.body.is_empty() {
-                self.format_missing_no_indent(item.span.hi() - BytePos(1));
-                self.block_indent = self.block_indent.block_unindent(self.config);
-                let indent_str = self.block_indent.to_string(self.config);
-                self.push_str(&indent_str);
-            } else {
-                for item in &item.body {
-                    self.format_body_element(item);
-                }
-
-                self.block_indent = self.block_indent.block_unindent(self.config);
-                self.format_missing_with_indent(item.span.hi() - BytePos(1));
-            }
-        }
-
-        self.push_str("}");
-        self.last_pos = item.span.hi();
-    }
-
-    fn format_body_element(&mut self, element: &BodyElement) {
-        match *element {
-            BodyElement::ForeignItem(item) => self.format_foreign_item(item),
-        }
-    }
-
-    pub fn format_foreign_mod(&mut self, fm: &ast::ForeignMod, span: Span) {
-        let item = Item::from_foreign_mod(fm, span, self.config);
-        self.format_item(&item);
-    }
-
-    fn format_foreign_item(&mut self, item: &ast::ForeignItem) {
-        let rewrite = item.rewrite(&self.get_context(), self.shape());
-        self.push_rewrite(item.span(), rewrite);
-        self.last_pos = item.span.hi();
-    }
-
-    pub fn rewrite_fn(
-        &mut self,
-        indent: Indent,
-        ident: ast::Ident,
-        fn_sig: &FnSig,
-        span: Span,
-        block: &ast::Block,
-    ) -> Option<String> {
-        let context = self.get_context();
-
-        let mut newline_brace = newline_for_brace(self.config, &fn_sig.generics.where_clause);
-
-        let (mut result, force_newline_brace) =
-            rewrite_fn_base(&context, indent, ident, fn_sig, span, newline_brace, true)?;
-
-        // 2 = ` {`
-        if self.config.brace_style() == BraceStyle::AlwaysNextLine || force_newline_brace
-            || last_line_width(&result) + 2 > self.shape().width
-        {
-            newline_brace = true;
-        } else if !result.contains('\n') {
-            newline_brace = false;
-        }
-
-        // Prepare for the function body by possibly adding a newline and
-        // indent.
-        // FIXME we'll miss anything between the end of the signature and the
-        // start of the body, but we need more spans from the compiler to solve
-        // this.
-        if newline_brace {
-            result.push('\n');
-            result.push_str(&indent.to_string(self.config));
-        } else {
-            result.push(' ');
-        }
-
-        self.single_line_fn(&result, block).or_else(|| Some(result))
-    }
-
-    pub fn rewrite_required_fn(
-        &mut self,
-        indent: Indent,
-        ident: ast::Ident,
-        sig: &ast::MethodSig,
-        generics: &ast::Generics,
-        span: Span,
-    ) -> Option<String> {
-        // Drop semicolon or it will be interpreted as comment.
-        let span = mk_sp(span.lo(), span.hi() - BytePos(1));
-        let context = self.get_context();
-
-        let (mut result, _) = rewrite_fn_base(
-            &context,
-            indent,
-            ident,
-            &FnSig::from_method_sig(sig, generics),
-            span,
-            false,
-            false,
-        )?;
-
-        // Re-attach semicolon
-        result.push(';');
-
-        Some(result)
-    }
-
-    fn single_line_fn(&self, fn_str: &str, block: &ast::Block) -> Option<String> {
-        if fn_str.contains('\n') {
-            return None;
-        }
-
-        let codemap = self.get_context().codemap;
-
-        if self.config.empty_item_single_line() && is_empty_block(block, codemap)
-            && self.block_indent.width() + fn_str.len() + 2 <= self.config.max_width()
-        {
-            return Some(format!("{}{{}}", fn_str));
-        }
-
-        if self.config.fn_single_line() && is_simple_block_stmt(block, codemap) {
-            let rewrite = {
-                if let Some(stmt) = block.stmts.first() {
-                    match stmt_expr(stmt) {
-                        Some(e) => {
-                            let suffix = if semicolon_for_expr(&self.get_context(), e) {
-                                ";"
-                            } else {
-                                ""
-                            };
-
-                            format_expr(e, ExprType::Statement, &self.get_context(), self.shape())
-                                .map(|s| s + suffix)
-                                .or_else(|| Some(self.snippet(e.span).to_owned()))
-                        }
-                        None => stmt.rewrite(&self.get_context(), self.shape()),
-                    }
-                } else {
-                    None
-                }
-            };
-
-            if let Some(res) = rewrite {
-                let width = self.block_indent.width() + fn_str.len() + res.len() + 4;
-                if !res.contains('\n') && width <= self.config.max_width() {
-                    return Some(format!("{}{{ {} }}", fn_str, res));
-                }
-            }
-        }
-
-        None
-    }
-
-    pub fn visit_static(&mut self, static_parts: &StaticParts) {
-        let rewrite = rewrite_static(&self.get_context(), static_parts, self.block_indent);
-        self.push_rewrite(static_parts.span, rewrite);
-    }
-
-    pub fn visit_struct(&mut self, struct_parts: &StructParts) {
-        let is_tuple = struct_parts.def.is_tuple();
-        let rewrite = format_struct(&self.get_context(), struct_parts, self.block_indent, None)
-            .map(|s| if is_tuple { s + ";" } else { s });
-        self.push_rewrite(struct_parts.span, rewrite);
-    }
-
-    pub fn visit_enum(
-        &mut self,
-        ident: ast::Ident,
-        vis: &ast::Visibility,
-        enum_def: &ast::EnumDef,
-        generics: &ast::Generics,
-        span: Span,
-    ) {
-        let enum_header = format_header("enum ", ident, vis);
-        self.push_str(&enum_header);
-
-        let enum_snippet = self.snippet(span);
-        let brace_pos = enum_snippet.find_uncommented("{").unwrap();
-        let body_start = span.lo() + BytePos(brace_pos as u32 + 1);
-        let generics_str = format_generics(
-            &self.get_context(),
-            generics,
-            self.config.brace_style(),
-            if enum_def.variants.is_empty() {
-                BracePos::ForceSameLine
-            } else {
-                BracePos::Auto
-            },
-            self.block_indent,
-            mk_sp(span.lo(), body_start),
-            last_line_width(&enum_header),
-        ).unwrap();
-        self.push_str(&generics_str);
-
-        self.last_pos = body_start;
-
-        self.block_indent = self.block_indent.block_indent(self.config);
-        let variant_list = self.format_variant_list(enum_def, body_start, span.hi() - BytePos(1));
-        match variant_list {
-            Some(ref body_str) => self.push_str(body_str),
-            None => self.format_missing_no_indent(span.hi() - BytePos(1)),
-        }
-        self.block_indent = self.block_indent.block_unindent(self.config);
-
-        if variant_list.is_some() || contains_comment(&enum_snippet[brace_pos..]) {
-            let indent_str = self.block_indent.to_string(self.config);
-            self.push_str(&indent_str);
-        }
-        self.push_str("}");
-        self.last_pos = span.hi();
-    }
-
-    // Format the body of an enum definition
-    fn format_variant_list(
-        &self,
-        enum_def: &ast::EnumDef,
-        body_lo: BytePos,
-        body_hi: BytePos,
-    ) -> Option<String> {
-        if enum_def.variants.is_empty() {
-            return None;
-        }
-        let mut result = String::with_capacity(1024);
-        result.push('\n');
-        let indentation = self.block_indent.to_string(self.config);
-        result.push_str(&indentation);
-
-        let itemize_list_with = |one_line_width: usize| {
-            itemize_list(
-                self.codemap,
-                enum_def.variants.iter(),
-                "}",
-                ",",
-                |f| {
-                    if !f.node.attrs.is_empty() {
-                        f.node.attrs[0].span.lo()
-                    } else {
-                        f.span.lo()
-                    }
-                },
-                |f| f.span.hi(),
-                |f| self.format_variant(f, one_line_width),
-                body_lo,
-                body_hi,
-                false,
-            ).collect()
-        };
-        let mut items: Vec<_> =
-            itemize_list_with(self.config.width_heuristics().struct_variant_width);
-        // If one of the variants use multiple lines, use multi-lined formatting for all variants.
-        let has_multiline_variant = items.iter().any(|item| item.inner_as_ref().contains('\n'));
-        let has_single_line_variant = items.iter().any(|item| !item.inner_as_ref().contains('\n'));
-        if has_multiline_variant && has_single_line_variant {
-            items = itemize_list_with(0);
-        }
-
-        let shape = self.shape().sub_width(2)?;
-        let fmt = ListFormatting {
-            tactic: DefinitiveListTactic::Vertical,
-            separator: ",",
-            trailing_separator: self.config.trailing_comma(),
-            separator_place: SeparatorPlace::Back,
-            shape,
-            ends_with_newline: true,
-            preserve_newline: true,
-            config: self.config,
-        };
-
-        let list = write_list(&items, &fmt)?;
-        result.push_str(&list);
-        result.push('\n');
-        Some(result)
-    }
-
-    // Variant of an enum.
-    fn format_variant(&self, field: &ast::Variant, one_line_width: usize) -> Option<String> {
-        if contains_skip(&field.node.attrs) {
-            let lo = field.node.attrs[0].span.lo();
-            let span = mk_sp(lo, field.span.hi());
-            return Some(self.snippet(span).to_owned());
-        }
-
-        let context = self.get_context();
-        // 1 = ','
-        let shape = self.shape().sub_width(1)?;
-        let attrs_str = field.node.attrs.rewrite(&context, shape)?;
-        let lo = field
-            .node
-            .attrs
-            .last()
-            .map_or(field.span.lo(), |attr| attr.span.hi());
-        let span = mk_sp(lo, field.span.lo());
-
-        let variant_body = match field.node.data {
-            ast::VariantData::Tuple(..) | ast::VariantData::Struct(..) => format_struct(
-                &context,
-                &StructParts::from_variant(field),
-                self.block_indent,
-                Some(one_line_width),
-            )?,
-            ast::VariantData::Unit(..) => {
-                if let Some(ref expr) = field.node.disr_expr {
-                    let lhs = format!("{} =", field.node.name);
-                    rewrite_assign_rhs(&context, lhs, &**expr, shape)?
-                } else {
-                    field.node.name.to_string()
-                }
-            }
-        };
-
-        combine_strs_with_missing_comments(&context, &attrs_str, &variant_body, span, shape, false)
-    }
-}
-
-pub fn format_impl(
-    context: &RewriteContext,
-    item: &ast::Item,
-    offset: Indent,
-    where_span_end: Option<BytePos>,
-) -> Option<String> {
-    if let ast::ItemKind::Impl(_, _, _, ref generics, _, ref self_ty, ref items) = item.node {
-        let mut result = String::with_capacity(128);
-        let ref_and_type = format_impl_ref_and_type(context, item, offset)?;
-        let indent_str = offset.to_string(context.config);
-        let sep = format!("\n{}", &indent_str);
-        result.push_str(&ref_and_type);
-
-        let where_budget = if result.contains('\n') {
-            context.config.max_width()
-        } else {
-            context.budget(last_line_width(&result))
-        };
-        let option = WhereClauseOption::snuggled(&ref_and_type);
-        let where_clause_str = rewrite_where_clause(
-            context,
-            &generics.where_clause,
-            context.config.brace_style(),
-            Shape::legacy(where_budget, offset.block_only()),
-            Density::Vertical,
-            "{",
-            where_span_end,
-            self_ty.span.hi(),
-            option,
-            false,
-        )?;
-
-        // If there is no where clause, we may have missing comments between the trait name and
-        // the opening brace.
-        if generics.where_clause.predicates.is_empty() {
-            if let Some(hi) = where_span_end {
-                match recover_missing_comment_in_span(
-                    mk_sp(self_ty.span.hi(), hi),
-                    Shape::indented(offset, context.config),
-                    context,
-                    last_line_width(&result),
-                ) {
-                    Some(ref missing_comment) if !missing_comment.is_empty() => {
-                        result.push_str(missing_comment);
-                    }
-                    _ => (),
-                }
-            }
-        }
-
-        if is_impl_single_line(context, items, &result, &where_clause_str, item)? {
-            result.push_str(&where_clause_str);
-            if where_clause_str.contains('\n') || last_line_contains_single_line_comment(&result) {
-                result.push_str(&format!("{}{{{}}}", &sep, &sep));
-            } else {
-                result.push_str(" {}");
-            }
-            return Some(result);
-        }
-
-        if !where_clause_str.is_empty() && !where_clause_str.contains('\n') {
-            result.push('\n');
-            let width = offset.block_indent + context.config.tab_spaces() - 1;
-            let where_indent = Indent::new(0, width);
-            result.push_str(&where_indent.to_string(context.config));
-        }
-        result.push_str(&where_clause_str);
-
-        let need_newline = !last_line_extendable(&result)
-            && (last_line_contains_single_line_comment(&result) || result.contains('\n'));
-        match context.config.brace_style() {
-            _ if need_newline => result.push_str(&sep),
-            BraceStyle::AlwaysNextLine => result.push_str(&sep),
-            BraceStyle::PreferSameLine => result.push(' '),
-            BraceStyle::SameLineWhere => {
-                if !where_clause_str.is_empty() {
-                    result.push_str(&sep);
-                } else {
-                    result.push(' ');
-                }
-            }
-        }
-
-        result.push('{');
-
-        let snippet = context.snippet(item.span);
-        let open_pos = snippet.find_uncommented("{")? + 1;
-
-        if !items.is_empty() || contains_comment(&snippet[open_pos..]) {
-            let mut visitor = FmtVisitor::from_context(context);
-            visitor.block_indent = offset.block_only().block_indent(context.config);
-            visitor.last_pos = item.span.lo() + BytePos(open_pos as u32);
-
-            visitor.visit_attrs(&item.attrs, ast::AttrStyle::Inner);
-            for item in items {
-                visitor.visit_impl_item(item);
-            }
-
-            visitor.format_missing(item.span.hi() - BytePos(1));
-
-            let inner_indent_str = visitor.block_indent.to_string(context.config);
-            let outer_indent_str = offset.block_only().to_string(context.config);
-
-            result.push('\n');
-            result.push_str(&inner_indent_str);
-            result.push_str(visitor.buffer.to_string().trim());
-            result.push('\n');
-            result.push_str(&outer_indent_str);
-        }
-
-        if result.ends_with('{') {
-            result.push_str(&sep);
-        }
-        result.push('}');
-
-        Some(result)
-    } else {
-        unreachable!();
-    }
-}
-
-fn is_impl_single_line(
-    context: &RewriteContext,
-    items: &[ImplItem],
-    result: &str,
-    where_clause_str: &str,
-    item: &ast::Item,
-) -> Option<bool> {
-    let snippet = context.snippet(item.span);
-    let open_pos = snippet.find_uncommented("{")? + 1;
-
-    Some(
-        context.config.empty_item_single_line() && items.is_empty() && !result.contains('\n')
-            && result.len() + where_clause_str.len() <= context.config.max_width()
-            && !contains_comment(&snippet[open_pos..]),
-    )
-}
-
-fn format_impl_ref_and_type(
-    context: &RewriteContext,
-    item: &ast::Item,
-    offset: Indent,
-) -> Option<String> {
-    if let ast::ItemKind::Impl(
-        unsafety,
-        polarity,
-        defaultness,
-        ref generics,
-        ref trait_ref,
-        ref self_ty,
-        _,
-    ) = item.node
-    {
-        let mut result = String::with_capacity(128);
-
-        result.push_str(&format_visibility(&item.vis));
-        result.push_str(format_defaultness(defaultness));
-        result.push_str(format_unsafety(unsafety));
-        result.push_str("impl");
-
-        let lo = context.codemap.span_after(item.span, "impl");
-        let hi = match *trait_ref {
-            Some(ref tr) => tr.path.span.lo(),
-            None => self_ty.span.lo(),
-        };
-        let shape = generics_shape_from_config(
-            context.config,
-            Shape::indented(offset + last_line_width(&result), context.config),
-            0,
-        )?;
-        let one_line_budget = shape.width.checked_sub(last_line_width(&result) + 2)?;
-        let generics_str =
-            rewrite_generics_inner(context, generics, shape, one_line_budget, mk_sp(lo, hi))?;
-
-        let polarity_str = if polarity == ast::ImplPolarity::Negative {
-            "!"
-        } else {
-            ""
-        };
-
-        if let Some(ref trait_ref) = *trait_ref {
-            let result_len = result.len();
-            if let Some(trait_ref_str) = rewrite_trait_ref(
-                context,
-                trait_ref,
-                offset,
-                &generics_str,
-                true,
-                polarity_str,
-                result_len,
-            ) {
-                result.push_str(&trait_ref_str);
-            } else {
-                let generics_str =
-                    rewrite_generics_inner(context, generics, shape, 0, mk_sp(lo, hi))?;
-                result.push_str(&rewrite_trait_ref(
-                    context,
-                    trait_ref,
-                    offset,
-                    &generics_str,
-                    false,
-                    polarity_str,
-                    result_len,
-                )?);
-            }
-        } else {
-            result.push_str(&generics_str);
-        }
-
-        // Try to put the self type in a single line.
-        // ` for`
-        let trait_ref_overhead = if trait_ref.is_some() { 4 } else { 0 };
-        let curly_brace_overhead = if generics.where_clause.predicates.is_empty() {
-            // If there is no where clause adapt budget for type formatting to take space and curly
-            // brace into account.
-            match context.config.brace_style() {
-                BraceStyle::AlwaysNextLine => 0,
-                _ => 2,
-            }
-        } else {
-            0
-        };
-        let used_space = last_line_width(&result) + trait_ref_overhead + curly_brace_overhead;
-        // 1 = space before the type.
-        let budget = context.budget(used_space + 1);
-        if let Some(self_ty_str) = self_ty.rewrite(context, Shape::legacy(budget, offset)) {
-            if !self_ty_str.contains('\n') {
-                if trait_ref.is_some() {
-                    result.push_str(" for ");
-                } else {
-                    result.push(' ');
-                }
-                result.push_str(&self_ty_str);
-                return Some(result);
-            }
-        }
-
-        // Couldn't fit the self type on a single line, put it on a new line.
-        result.push('\n');
-        // Add indentation of one additional tab.
-        let new_line_offset = offset.block_indent(context.config);
-        result.push_str(&new_line_offset.to_string(context.config));
-        if trait_ref.is_some() {
-            result.push_str("for ");
-        }
-        let budget = context.budget(last_line_width(&result));
-        let type_offset = match context.config.indent_style() {
-            IndentStyle::Visual => new_line_offset + trait_ref_overhead,
-            IndentStyle::Block => new_line_offset,
-        };
-        result.push_str(&*self_ty.rewrite(context, Shape::legacy(budget, type_offset))?);
-        Some(result)
-    } else {
-        unreachable!();
-    }
-}
-
-fn rewrite_trait_ref(
-    context: &RewriteContext,
-    trait_ref: &ast::TraitRef,
-    offset: Indent,
-    generics_str: &str,
-    retry: bool,
-    polarity_str: &str,
-    result_len: usize,
-) -> Option<String> {
-    // 1 = space between generics and trait_ref
-    let used_space = 1 + polarity_str.len() + last_line_used_width(generics_str, result_len);
-    let shape = Shape::indented(offset + used_space, context.config);
-    if let Some(trait_ref_str) = trait_ref.rewrite(context, shape) {
-        if !(retry && trait_ref_str.contains('\n')) {
-            return Some(format!(
-                "{} {}{}",
-                generics_str, polarity_str, &trait_ref_str
-            ));
-        }
-    }
-    // We could not make enough space for trait_ref, so put it on new line.
-    if !retry {
-        let offset = offset.block_indent(context.config);
-        let shape = Shape::indented(offset, context.config);
-        let trait_ref_str = trait_ref.rewrite(context, shape)?;
-        Some(format!(
-            "{}\n{}{}{}",
-            generics_str,
-            &offset.to_string(context.config),
-            polarity_str,
-            &trait_ref_str
-        ))
-    } else {
-        None
-    }
-}
-
-pub struct StructParts<'a> {
-    prefix: &'a str,
-    ident: ast::Ident,
-    vis: &'a ast::Visibility,
-    def: &'a ast::VariantData,
-    generics: Option<&'a ast::Generics>,
-    span: Span,
-}
-
-impl<'a> StructParts<'a> {
-    fn format_header(&self) -> String {
-        format_header(self.prefix, self.ident, self.vis)
-    }
-
-    fn from_variant(variant: &'a ast::Variant) -> Self {
-        StructParts {
-            prefix: "",
-            ident: variant.node.name,
-            vis: &ast::Visibility::Inherited,
-            def: &variant.node.data,
-            generics: None,
-            span: variant.span,
-        }
-    }
-
-    pub fn from_item(item: &'a ast::Item) -> Self {
-        let (prefix, def, generics) = match item.node {
-            ast::ItemKind::Struct(ref def, ref generics) => ("struct ", def, generics),
-            ast::ItemKind::Union(ref def, ref generics) => ("union ", def, generics),
-            _ => unreachable!(),
-        };
-        StructParts {
-            prefix,
-            ident: item.ident,
-            vis: &item.vis,
-            def,
-            generics: Some(generics),
-            span: item.span,
-        }
-    }
-}
-
-fn format_struct(
-    context: &RewriteContext,
-    struct_parts: &StructParts,
-    offset: Indent,
-    one_line_width: Option<usize>,
-) -> Option<String> {
-    match *struct_parts.def {
-        ast::VariantData::Unit(..) => format_unit_struct(context, struct_parts, offset),
-        ast::VariantData::Tuple(ref fields, _) => {
-            format_tuple_struct(context, struct_parts, fields, offset)
-        }
-        ast::VariantData::Struct(ref fields, _) => {
-            format_struct_struct(context, struct_parts, fields, offset, one_line_width)
-        }
-    }
-}
-
-pub fn format_trait(context: &RewriteContext, item: &ast::Item, offset: Indent) -> Option<String> {
-    if let ast::ItemKind::Trait(_, unsafety, ref generics, ref type_param_bounds, ref trait_items) =
-        item.node
-    {
-        let mut result = String::with_capacity(128);
-        let header = format!(
-            "{}{}trait {}",
-            format_visibility(&item.vis),
-            format_unsafety(unsafety),
-            item.ident
-        );
-
-        result.push_str(&header);
-
-        let body_lo = context.codemap.span_after(item.span, "{");
-
-        let shape = Shape::indented(offset, context.config).offset_left(result.len())?;
-        let generics_str =
-            rewrite_generics(context, generics, shape, mk_sp(item.span.lo(), body_lo))?;
-        result.push_str(&generics_str);
-
-        // FIXME(#2055): rustfmt fails to format when there are comments between trait bounds.
-        if !type_param_bounds.is_empty() {
-            let ident_hi = context
-                .codemap
-                .span_after(item.span, &format!("{}", item.ident));
-            let bound_hi = type_param_bounds.last().unwrap().span().hi();
-            let snippet = context.snippet(mk_sp(ident_hi, bound_hi));
-            if contains_comment(snippet) {
-                return None;
-            }
-        }
-        let trait_bound_str = rewrite_trait_bounds(
-            context,
-            type_param_bounds,
-            Shape::indented(offset, context.config),
-        )?;
-        // If the trait, generics, and trait bound cannot fit on the same line,
-        // put the trait bounds on an indented new line
-        if offset.width() + last_line_width(&result) + trait_bound_str.len()
-            > context.config.comment_width()
-        {
-            result.push('\n');
-            let trait_indent = offset.block_only().block_indent(context.config);
-            result.push_str(&trait_indent.to_string(context.config));
-        }
-        result.push_str(&trait_bound_str);
-
-        let where_density =
-            if context.config.indent_style() == IndentStyle::Block && result.is_empty() {
-                Density::Compressed
-            } else {
-                Density::Tall
-            };
-
-        let where_budget = context.budget(last_line_width(&result));
-        let pos_before_where = if type_param_bounds.is_empty() {
-            generics.where_clause.span.lo()
-        } else {
-            type_param_bounds[type_param_bounds.len() - 1].span().hi()
-        };
-        let option = WhereClauseOption::snuggled(&generics_str);
-        let where_clause_str = rewrite_where_clause(
-            context,
-            &generics.where_clause,
-            context.config.brace_style(),
-            Shape::legacy(where_budget, offset.block_only()),
-            where_density,
-            "{",
-            None,
-            pos_before_where,
-            option,
-            false,
-        )?;
-        // If the where clause cannot fit on the same line,
-        // put the where clause on a new line
-        if !where_clause_str.contains('\n')
-            && last_line_width(&result) + where_clause_str.len() + offset.width()
-                > context.config.comment_width()
-        {
-            result.push('\n');
-            let width = offset.block_indent + context.config.tab_spaces() - 1;
-            let where_indent = Indent::new(0, width);
-            result.push_str(&where_indent.to_string(context.config));
-        }
-        result.push_str(&where_clause_str);
-
-        if generics.where_clause.predicates.is_empty() {
-            let item_snippet = context.snippet(item.span);
-            if let Some(lo) = item_snippet.chars().position(|c| c == '/') {
-                // 1 = `{`
-                let comment_hi = body_lo - BytePos(1);
-                let comment_lo = item.span.lo() + BytePos(lo as u32);
-                if comment_lo < comment_hi {
-                    match recover_missing_comment_in_span(
-                        mk_sp(comment_lo, comment_hi),
-                        Shape::indented(offset, context.config),
-                        context,
-                        last_line_width(&result),
-                    ) {
-                        Some(ref missing_comment) if !missing_comment.is_empty() => {
-                            result.push_str(missing_comment);
-                        }
-                        _ => (),
-                    }
-                }
-            }
-        }
-
-        match context.config.brace_style() {
-            _ if last_line_contains_single_line_comment(&result) => {
-                result.push('\n');
-                result.push_str(&offset.to_string(context.config));
-            }
-            BraceStyle::AlwaysNextLine => {
-                result.push('\n');
-                result.push_str(&offset.to_string(context.config));
-            }
-            BraceStyle::PreferSameLine => result.push(' '),
-            BraceStyle::SameLineWhere => {
-                if !where_clause_str.is_empty()
-                    && (!trait_items.is_empty() || result.contains('\n'))
-                {
-                    result.push('\n');
-                    result.push_str(&offset.to_string(context.config));
-                } else {
-                    result.push(' ');
-                }
-            }
-        }
-        result.push('{');
-
-        let snippet = context.snippet(item.span);
-        let open_pos = snippet.find_uncommented("{")? + 1;
-
-        if !trait_items.is_empty() || contains_comment(&snippet[open_pos..]) {
-            let mut visitor = FmtVisitor::from_context(context);
-            visitor.block_indent = offset.block_only().block_indent(context.config);
-            visitor.last_pos = item.span.lo() + BytePos(open_pos as u32);
-
-            for item in trait_items {
-                visitor.visit_trait_item(item);
-            }
-
-            visitor.format_missing(item.span.hi() - BytePos(1));
-
-            let inner_indent_str = visitor.block_indent.to_string(context.config);
-            let outer_indent_str = offset.block_only().to_string(context.config);
-
-            result.push('\n');
-            result.push_str(&inner_indent_str);
-            result.push_str(visitor.buffer.to_string().trim());
-            result.push('\n');
-            result.push_str(&outer_indent_str);
-        } else if result.contains('\n') {
-            result.push('\n');
-        }
-
-        result.push('}');
-        Some(result)
-    } else {
-        unreachable!();
-    }
-}
-
-pub fn format_trait_alias(
-    context: &RewriteContext,
-    ident: ast::Ident,
-    generics: &ast::Generics,
-    ty_param_bounds: &ast::TyParamBounds,
-    shape: Shape,
-) -> Option<String> {
-    let alias = ident.name.as_str();
-    // 6 = "trait ", 2 = " ="
-    let g_shape = shape.offset_left(6 + alias.len())?.sub_width(2)?;
-    let generics_str = rewrite_generics(context, generics, g_shape, generics.span)?;
-    let lhs = format!("trait {}{} =", alias, generics_str);
-    // 1 = ";"
-    rewrite_assign_rhs(context, lhs, ty_param_bounds, shape.sub_width(1)?).map(|s| s + ";")
-}
-
-fn format_unit_struct(context: &RewriteContext, p: &StructParts, offset: Indent) -> Option<String> {
-    let header_str = format_header(p.prefix, p.ident, p.vis);
-    let generics_str = if let Some(generics) = p.generics {
-        let hi = if generics.where_clause.predicates.is_empty() {
-            generics.span.hi()
-        } else {
-            generics.where_clause.span.hi()
-        };
-        format_generics(
-            context,
-            generics,
-            context.config.brace_style(),
-            BracePos::None,
-            offset,
-            mk_sp(generics.span.lo(), hi),
-            last_line_width(&header_str),
-        )?
-    } else {
-        String::new()
-    };
-    Some(format!("{}{};", header_str, generics_str))
-}
-
-pub fn format_struct_struct(
-    context: &RewriteContext,
-    struct_parts: &StructParts,
-    fields: &[ast::StructField],
-    offset: Indent,
-    one_line_width: Option<usize>,
-) -> Option<String> {
-    let mut result = String::with_capacity(1024);
-    let span = struct_parts.span;
-
-    let header_str = struct_parts.format_header();
-    result.push_str(&header_str);
-
-    let header_hi = span.lo() + BytePos(header_str.len() as u32);
-    let body_lo = context.codemap.span_after(span, "{");
-
-    let generics_str = match struct_parts.generics {
-        Some(g) => format_generics(
-            context,
-            g,
-            context.config.brace_style(),
-            if fields.is_empty() {
-                BracePos::ForceSameLine
-            } else {
-                BracePos::Auto
-            },
-            offset,
-            mk_sp(header_hi, body_lo),
-            last_line_width(&result),
-        )?,
-        None => {
-            // 3 = ` {}`, 2 = ` {`.
-            let overhead = if fields.is_empty() { 3 } else { 2 };
-            if (context.config.brace_style() == BraceStyle::AlwaysNextLine && !fields.is_empty())
-                || context.config.max_width() < overhead + result.len()
-            {
-                format!("\n{}{{", offset.block_only().to_string(context.config))
-            } else {
-                " {".to_owned()
-            }
-        }
-    };
-    // 1 = `}`
-    let overhead = if fields.is_empty() { 1 } else { 0 };
-    let total_width = result.len() + generics_str.len() + overhead;
-    if !generics_str.is_empty() && !generics_str.contains('\n')
-        && total_width > context.config.max_width()
-    {
-        result.push('\n');
-        result.push_str(&offset.to_string(context.config));
-        result.push_str(generics_str.trim_left());
-    } else {
-        result.push_str(&generics_str);
-    }
-
-    if fields.is_empty() {
-        let snippet = context.snippet(mk_sp(body_lo, span.hi() - BytePos(1)));
-        if snippet.trim().is_empty() {
-            // `struct S {}`
-        } else if snippet.trim_right_matches(&[' ', '\t'][..]).ends_with('\n') {
-            // fix indent
-            result.push_str(snippet.trim_right());
-            result.push('\n');
-            result.push_str(&offset.to_string(context.config));
-        } else {
-            result.push_str(snippet);
-        }
-        result.push('}');
-        return Some(result);
-    }
-
-    // 3 = ` ` and ` }`
-    let one_line_budget = context.budget(result.len() + 3 + offset.width());
-    let one_line_budget =
-        one_line_width.map_or(0, |one_line_width| min(one_line_width, one_line_budget));
-
-    let items_str = rewrite_with_alignment(
-        fields,
-        context,
-        Shape::indented(offset, context.config).sub_width(1)?,
-        mk_sp(body_lo, span.hi()),
-        one_line_budget,
-    )?;
-
-    if !items_str.contains('\n') && !result.contains('\n') && items_str.len() <= one_line_budget {
-        Some(format!("{} {} }}", result, items_str))
-    } else {
-        Some(format!(
-            "{}\n{}{}\n{}}}",
-            result,
-            offset
-                .block_indent(context.config)
-                .to_string(context.config),
-            items_str,
-            offset.to_string(context.config)
-        ))
-    }
-}
-
-/// Returns a bytepos that is after that of `(` in `pub(..)`. If the given visibility does not
-/// contain `pub(..)`, then return the `lo` of the `defualt_span`. Yeah, but for what? Well, we need
-/// to bypass the `(` in the visibility when creating a span of tuple's body or fn's args.
-fn get_bytepos_after_visibility(
-    context: &RewriteContext,
-    vis: &ast::Visibility,
-    default_span: Span,
-    terminator: &str,
-) -> BytePos {
-    match *vis {
-        ast::Visibility::Crate(s, CrateSugar::PubCrate) => context
-            .codemap
-            .span_after(mk_sp(s.hi(), default_span.hi()), terminator),
-        ast::Visibility::Crate(s, CrateSugar::JustCrate) => s.hi(),
-        ast::Visibility::Restricted { ref path, .. } => path.span.hi(),
-        _ => default_span.lo(),
-    }
-}
-
-fn format_tuple_struct(
-    context: &RewriteContext,
-    struct_parts: &StructParts,
-    fields: &[ast::StructField],
-    offset: Indent,
-) -> Option<String> {
-    let mut result = String::with_capacity(1024);
-    let span = struct_parts.span;
-
-    let header_str = struct_parts.format_header();
-    result.push_str(&header_str);
-
-    let body_lo = if fields.is_empty() {
-        let lo = get_bytepos_after_visibility(context, struct_parts.vis, span, ")");
-        context.codemap.span_after(mk_sp(lo, span.hi()), "(")
-    } else {
-        fields[0].span.lo()
-    };
-    let body_hi = if fields.is_empty() {
-        context.codemap.span_after(mk_sp(body_lo, span.hi()), ")")
-    } else {
-        // This is a dirty hack to work around a missing `)` from the span of the last field.
-        let last_arg_span = fields[fields.len() - 1].span;
-        if context.snippet(last_arg_span).ends_with(')') {
-            last_arg_span.hi()
-        } else {
-            context
-                .codemap
-                .span_after(mk_sp(last_arg_span.hi(), span.hi()), ")")
-        }
-    };
-
-    let where_clause_str = match struct_parts.generics {
-        Some(generics) => {
-            let budget = context.budget(last_line_width(&header_str));
-            let shape = Shape::legacy(budget, offset);
-            let g_span = mk_sp(span.lo(), body_lo);
-            let generics_str = rewrite_generics(context, generics, shape, g_span)?;
-            result.push_str(&generics_str);
-
-            let where_budget = context.budget(last_line_width(&result));
-            let option = WhereClauseOption::new(true, false);
-            rewrite_where_clause(
-                context,
-                &generics.where_clause,
-                context.config.brace_style(),
-                Shape::legacy(where_budget, offset.block_only()),
-                Density::Compressed,
-                ";",
-                None,
-                body_hi,
-                option,
-                false,
-            )?
-        }
-        None => "".to_owned(),
-    };
-
-    if fields.is_empty() {
-        // 3 = `();`
-        let used_width = last_line_used_width(&result, offset.width()) + 3;
-        if used_width > context.config.max_width() {
-            result.push('\n');
-            result.push_str(&offset
-                .block_indent(context.config)
-                .to_string(context.config))
-        }
-        result.push('(');
-        let snippet = context.snippet(mk_sp(
-            body_lo,
-            context.codemap.span_before(mk_sp(body_lo, span.hi()), ")"),
-        ));
-        if snippet.is_empty() {
-            // `struct S ()`
-        } else if snippet.trim_right_matches(&[' ', '\t'][..]).ends_with('\n') {
-            result.push_str(snippet.trim_right());
-            result.push('\n');
-            result.push_str(&offset.to_string(context.config));
-        } else {
-            result.push_str(snippet);
-        }
-        result.push(')');
-    } else {
-        let shape = Shape::indented(offset, context.config).sub_width(1)?;
-        let fields = &fields.iter().collect::<Vec<_>>()[..];
-        let one_line_width = context.config.width_heuristics().fn_call_width;
-        result = rewrite_call_inner(context, &result, fields, span, shape, one_line_width, false)?;
-    }
-
-    if !where_clause_str.is_empty() && !where_clause_str.contains('\n')
-        && (result.contains('\n')
-            || offset.block_indent + result.len() + where_clause_str.len() + 1
-                > context.config.max_width())
-    {
-        // We need to put the where clause on a new line, but we didn't
-        // know that earlier, so the where clause will not be indented properly.
-        result.push('\n');
-        result
-            .push_str(&(offset.block_only() + (context.config.tab_spaces() - 1))
-                .to_string(context.config));
-    }
-    result.push_str(&where_clause_str);
-
-    Some(result)
-}
-
-pub fn rewrite_type_alias(
-    context: &RewriteContext,
-    indent: Indent,
-    ident: ast::Ident,
-    ty: &ast::Ty,
-    generics: &ast::Generics,
-    vis: &ast::Visibility,
-    span: Span,
-) -> Option<String> {
-    let mut result = String::with_capacity(128);
-
-    result.push_str(&format_visibility(vis));
-    result.push_str("type ");
-    result.push_str(&ident.to_string());
-
-    // 2 = `= `
-    let g_shape = Shape::indented(indent, context.config)
-        .offset_left(result.len())?
-        .sub_width(2)?;
-    let g_span = mk_sp(context.codemap.span_after(span, "type"), ty.span.lo());
-    let generics_str = rewrite_generics(context, generics, g_shape, g_span)?;
-    result.push_str(&generics_str);
-
-    let where_budget = context.budget(last_line_width(&result));
-    let option = WhereClauseOption::snuggled(&result);
-    let where_clause_str = rewrite_where_clause(
-        context,
-        &generics.where_clause,
-        context.config.brace_style(),
-        Shape::legacy(where_budget, indent),
-        Density::Vertical,
-        "=",
-        Some(span.hi()),
-        generics.span.hi(),
-        option,
-        false,
-    )?;
-    result.push_str(&where_clause_str);
-    if where_clause_str.is_empty() {
-        result.push_str(" =");
-    } else {
-        result.push_str(&format!("\n{}=", indent.to_string(context.config)));
-    }
-
-    // 1 = ";"
-    let ty_shape = Shape::indented(indent, context.config).sub_width(1)?;
-    rewrite_assign_rhs(context, result, ty, ty_shape).map(|s| s + ";")
-}
-
-fn type_annotation_spacing(config: &Config) -> (&str, &str) {
-    (
-        if config.space_before_colon() { " " } else { "" },
-        if config.space_after_colon() { " " } else { "" },
-    )
-}
-
-pub fn rewrite_struct_field_prefix(
-    context: &RewriteContext,
-    field: &ast::StructField,
-) -> Option<String> {
-    let vis = format_visibility(&field.vis);
-    let type_annotation_spacing = type_annotation_spacing(context.config);
-    Some(match field.ident {
-        Some(name) => format!("{}{}{}:", vis, name, type_annotation_spacing.0),
-        None => format!("{}", vis),
-    })
-}
-
-impl Rewrite for ast::StructField {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        rewrite_struct_field(context, self, shape, 0)
-    }
-}
-
-pub fn rewrite_struct_field(
-    context: &RewriteContext,
-    field: &ast::StructField,
-    shape: Shape,
-    lhs_max_width: usize,
-) -> Option<String> {
-    if contains_skip(&field.attrs) {
-        return Some(context.snippet(field.span()).to_owned());
-    }
-
-    let type_annotation_spacing = type_annotation_spacing(context.config);
-    let prefix = rewrite_struct_field_prefix(context, field)?;
-
-    let attrs_str = field.attrs.rewrite(context, shape)?;
-    let attrs_extendable = field.ident.is_none() && is_attributes_extendable(&attrs_str);
-    let missing_span = if field.attrs.is_empty() {
-        mk_sp(field.span.lo(), field.span.lo())
-    } else {
-        mk_sp(field.attrs.last().unwrap().span.hi(), field.span.lo())
-    };
-    let mut spacing = String::from(if field.ident.is_some() {
-        type_annotation_spacing.1
-    } else {
-        ""
-    });
-    // Try to put everything on a single line.
-    let attr_prefix = combine_strs_with_missing_comments(
-        context,
-        &attrs_str,
-        &prefix,
-        missing_span,
-        shape,
-        attrs_extendable,
-    )?;
-    let overhead = last_line_width(&attr_prefix);
-    let lhs_offset = lhs_max_width.checked_sub(overhead).unwrap_or(0);
-    for _ in 0..lhs_offset {
-        spacing.push(' ');
-    }
-    // In this extreme case we will be missing a space betweeen an attribute and a field.
-    if prefix.is_empty() && !attrs_str.is_empty() && attrs_extendable && spacing.is_empty() {
-        spacing.push(' ');
-    }
-    let orig_ty = shape
-        .offset_left(overhead + spacing.len())
-        .and_then(|ty_shape| field.ty.rewrite(context, ty_shape));
-    if let Some(ref ty) = orig_ty {
-        if !ty.contains('\n') {
-            return Some(attr_prefix + &spacing + ty);
-        }
-    }
-
-    let is_prefix_empty = prefix.is_empty();
-    // We must use multiline. We are going to put attributes and a field on different lines.
-    let field_str = rewrite_assign_rhs(context, prefix, &*field.ty, shape)?;
-    // Remove a leading white-space from `rewrite_assign_rhs()` when rewriting a tuple struct.
-    let field_str = if is_prefix_empty {
-        field_str.trim_left()
-    } else {
-        &field_str
-    };
-    combine_strs_with_missing_comments(context, &attrs_str, field_str, missing_span, shape, false)
-}
-
-pub struct StaticParts<'a> {
-    prefix: &'a str,
-    vis: &'a ast::Visibility,
-    ident: ast::Ident,
-    ty: &'a ast::Ty,
-    mutability: ast::Mutability,
-    expr_opt: Option<&'a ptr::P<ast::Expr>>,
-    defaultness: Option<ast::Defaultness>,
-    span: Span,
-}
-
-impl<'a> StaticParts<'a> {
-    pub fn from_item(item: &'a ast::Item) -> Self {
-        let (prefix, ty, mutability, expr) = match item.node {
-            ast::ItemKind::Static(ref ty, mutability, ref expr) => ("static", ty, mutability, expr),
-            ast::ItemKind::Const(ref ty, ref expr) => {
-                ("const", ty, ast::Mutability::Immutable, expr)
-            }
-            _ => unreachable!(),
-        };
-        StaticParts {
-            prefix,
-            vis: &item.vis,
-            ident: item.ident,
-            ty,
-            mutability,
-            expr_opt: Some(expr),
-            defaultness: None,
-            span: item.span,
-        }
-    }
-
-    pub fn from_trait_item(ti: &'a ast::TraitItem) -> Self {
-        let (ty, expr_opt) = match ti.node {
-            ast::TraitItemKind::Const(ref ty, ref expr_opt) => (ty, expr_opt),
-            _ => unreachable!(),
-        };
-        StaticParts {
-            prefix: "const",
-            vis: &ast::Visibility::Inherited,
-            ident: ti.ident,
-            ty,
-            mutability: ast::Mutability::Immutable,
-            expr_opt: expr_opt.as_ref(),
-            defaultness: None,
-            span: ti.span,
-        }
-    }
-
-    pub fn from_impl_item(ii: &'a ast::ImplItem) -> Self {
-        let (ty, expr) = match ii.node {
-            ast::ImplItemKind::Const(ref ty, ref expr) => (ty, expr),
-            _ => unreachable!(),
-        };
-        StaticParts {
-            prefix: "const",
-            vis: &ii.vis,
-            ident: ii.ident,
-            ty,
-            mutability: ast::Mutability::Immutable,
-            expr_opt: Some(expr),
-            defaultness: Some(ii.defaultness),
-            span: ii.span,
-        }
-    }
-}
-
-fn rewrite_static(
-    context: &RewriteContext,
-    static_parts: &StaticParts,
-    offset: Indent,
-) -> Option<String> {
-    let colon = colon_spaces(
-        context.config.space_before_colon(),
-        context.config.space_after_colon(),
-    );
-    let mut prefix = format!(
-        "{}{}{} {}{}{}",
-        format_visibility(static_parts.vis),
-        static_parts.defaultness.map_or("", format_defaultness),
-        static_parts.prefix,
-        format_mutability(static_parts.mutability),
-        static_parts.ident,
-        colon,
-    );
-    // 2 = " =".len()
-    let ty_shape =
-        Shape::indented(offset.block_only(), context.config).offset_left(prefix.len() + 2)?;
-    let ty_str = match static_parts.ty.rewrite(context, ty_shape) {
-        Some(ty_str) => ty_str,
-        None => {
-            if prefix.ends_with(' ') {
-                prefix.pop();
-            }
-            let nested_indent = offset.block_indent(context.config);
-            let nested_shape = Shape::indented(nested_indent, context.config);
-            let ty_str = static_parts.ty.rewrite(context, nested_shape)?;
-            format!("\n{}{}", nested_indent.to_string(context.config), ty_str)
-        }
-    };
-
-    if let Some(expr) = static_parts.expr_opt {
-        let lhs = format!("{}{} =", prefix, ty_str);
-        // 1 = ;
-        let remaining_width = context.budget(offset.block_indent + 1);
-        rewrite_assign_rhs(
-            context,
-            lhs,
-            &**expr,
-            Shape::legacy(remaining_width, offset.block_only()),
-        ).and_then(|res| recover_comment_removed(res, static_parts.span, context))
-            .map(|s| if s.ends_with(';') { s } else { s + ";" })
-    } else {
-        Some(format!("{}{};", prefix, ty_str))
-    }
-}
-
-pub fn rewrite_associated_type(
-    ident: ast::Ident,
-    ty_opt: Option<&ptr::P<ast::Ty>>,
-    ty_param_bounds_opt: Option<&ast::TyParamBounds>,
-    context: &RewriteContext,
-    indent: Indent,
-) -> Option<String> {
-    let prefix = format!("type {}", ident);
-
-    let type_bounds_str = if let Some(bounds) = ty_param_bounds_opt {
-        // 2 = ": ".len()
-        let shape = Shape::indented(indent, context.config).offset_left(prefix.len() + 2)?;
-        let bound_str = bounds
-            .iter()
-            .map(|ty_bound| ty_bound.rewrite(context, shape))
-            .collect::<Option<Vec<_>>>()?;
-        if !bounds.is_empty() {
-            format!(": {}", join_bounds(context, shape, &bound_str))
-        } else {
-            String::new()
-        }
-    } else {
-        String::new()
-    };
-
-    if let Some(ty) = ty_opt {
-        // 1 = `;`
-        let shape = Shape::indented(indent, context.config).sub_width(1)?;
-        let lhs = format!("{}{} =", prefix, type_bounds_str);
-        rewrite_assign_rhs(context, lhs, &**ty, shape).map(|s| s + ";")
-    } else {
-        Some(format!("{}{};", prefix, type_bounds_str))
-    }
-}
-
-pub fn rewrite_associated_impl_type(
-    ident: ast::Ident,
-    defaultness: ast::Defaultness,
-    ty_opt: Option<&ptr::P<ast::Ty>>,
-    ty_param_bounds_opt: Option<&ast::TyParamBounds>,
-    context: &RewriteContext,
-    indent: Indent,
-) -> Option<String> {
-    let result = rewrite_associated_type(ident, ty_opt, ty_param_bounds_opt, context, indent)?;
-
-    match defaultness {
-        ast::Defaultness::Default => Some(format!("default {}", result)),
-        _ => Some(result),
-    }
-}
-
-impl Rewrite for ast::FunctionRetTy {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        match *self {
-            ast::FunctionRetTy::Default(_) => Some(String::new()),
-            ast::FunctionRetTy::Ty(ref ty) => {
-                let inner_width = shape.width.checked_sub(3)?;
-                ty.rewrite(context, Shape::legacy(inner_width, shape.indent + 3))
-                    .map(|r| format!("-> {}", r))
-            }
-        }
-    }
-}
-
-fn is_empty_infer(context: &RewriteContext, ty: &ast::Ty) -> bool {
-    match ty.node {
-        ast::TyKind::Infer => {
-            let original = context.snippet(ty.span);
-            original != "_"
-        }
-        _ => false,
-    }
-}
-
-impl Rewrite for ast::Arg {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        if is_named_arg(self) {
-            let mut result = self.pat
-                .rewrite(context, Shape::legacy(shape.width, shape.indent))?;
-
-            if !is_empty_infer(context, &*self.ty) {
-                if context.config.space_before_colon() {
-                    result.push_str(" ");
-                }
-                result.push_str(":");
-                if context.config.space_after_colon() {
-                    result.push_str(" ");
-                }
-                let overhead = last_line_width(&result);
-                let max_width = shape.width.checked_sub(overhead)?;
-                let ty_str = self.ty
-                    .rewrite(context, Shape::legacy(max_width, shape.indent))?;
-                result.push_str(&ty_str);
-            }
-
-            Some(result)
-        } else {
-            self.ty.rewrite(context, shape)
-        }
-    }
-}
-
-fn rewrite_explicit_self(
-    explicit_self: &ast::ExplicitSelf,
-    args: &[ast::Arg],
-    context: &RewriteContext,
-) -> Option<String> {
-    match explicit_self.node {
-        ast::SelfKind::Region(lt, m) => {
-            let mut_str = format_mutability(m);
-            match lt {
-                Some(ref l) => {
-                    let lifetime_str = l.rewrite(
-                        context,
-                        Shape::legacy(context.config.max_width(), Indent::empty()),
-                    )?;
-                    Some(format!("&{} {}self", lifetime_str, mut_str))
-                }
-                None => Some(format!("&{}self", mut_str)),
-            }
-        }
-        ast::SelfKind::Explicit(ref ty, _) => {
-            assert!(!args.is_empty(), "&[ast::Arg] shouldn't be empty.");
-
-            let mutability = explicit_self_mutability(&args[0]);
-            let type_str = ty.rewrite(
-                context,
-                Shape::legacy(context.config.max_width(), Indent::empty()),
-            )?;
-
-            Some(format!(
-                "{}self: {}",
-                format_mutability(mutability),
-                type_str
-            ))
-        }
-        ast::SelfKind::Value(_) => {
-            assert!(!args.is_empty(), "&[ast::Arg] shouldn't be empty.");
-
-            let mutability = explicit_self_mutability(&args[0]);
-
-            Some(format!("{}self", format_mutability(mutability)))
-        }
-    }
-}
-
-// Hacky solution caused by absence of `Mutability` in `SelfValue` and
-// `SelfExplicit` variants of `ast::ExplicitSelf_`.
-fn explicit_self_mutability(arg: &ast::Arg) -> ast::Mutability {
-    if let ast::PatKind::Ident(ast::BindingMode::ByValue(mutability), _, _) = arg.pat.node {
-        mutability
-    } else {
-        unreachable!()
-    }
-}
-
-pub fn span_lo_for_arg(arg: &ast::Arg) -> BytePos {
-    if is_named_arg(arg) {
-        arg.pat.span.lo()
-    } else {
-        arg.ty.span.lo()
-    }
-}
-
-pub fn span_hi_for_arg(context: &RewriteContext, arg: &ast::Arg) -> BytePos {
-    match arg.ty.node {
-        ast::TyKind::Infer if context.snippet(arg.ty.span) == "_" => arg.ty.span.hi(),
-        ast::TyKind::Infer if is_named_arg(arg) => arg.pat.span.hi(),
-        _ => arg.ty.span.hi(),
-    }
-}
-
-pub fn is_named_arg(arg: &ast::Arg) -> bool {
-    if let ast::PatKind::Ident(_, ident, _) = arg.pat.node {
-        ident.node != symbol::keywords::Invalid.ident()
-    } else {
-        true
-    }
-}
-
-// Return type is (result, force_new_line_for_brace)
-fn rewrite_fn_base(
-    context: &RewriteContext,
-    indent: Indent,
-    ident: ast::Ident,
-    fn_sig: &FnSig,
-    span: Span,
-    newline_brace: bool,
-    has_body: bool,
-) -> Option<(String, bool)> {
-    let mut force_new_line_for_brace = false;
-
-    let where_clause = &fn_sig.generics.where_clause;
-
-    let mut result = String::with_capacity(1024);
-    result.push_str(&fn_sig.to_str(context));
-
-    // fn foo
-    result.push_str("fn ");
-    result.push_str(&ident.to_string());
-
-    // Generics.
-    let overhead = if has_body && !newline_brace {
-        // 4 = `() {`
-        4
-    } else {
-        // 2 = `()`
-        2
-    };
-    let used_width = last_line_used_width(&result, indent.width());
-    let one_line_budget = context.budget(used_width + overhead);
-    let shape = Shape {
-        width: one_line_budget,
-        indent,
-        offset: used_width,
-    };
-    let fd = fn_sig.decl;
-    let g_span = mk_sp(span.lo(), fd.output.span().lo());
-    let generics_str = rewrite_generics(context, fn_sig.generics, shape, g_span)?;
-    result.push_str(&generics_str);
-
-    let snuggle_angle_bracket = generics_str
-        .lines()
-        .last()
-        .map_or(false, |l| l.trim_left().len() == 1);
-
-    // Note that the width and indent don't really matter, we'll re-layout the
-    // return type later anyway.
-    let ret_str = fd.output
-        .rewrite(context, Shape::indented(indent, context.config))?;
-
-    let multi_line_ret_str = ret_str.contains('\n');
-    let ret_str_len = if multi_line_ret_str { 0 } else { ret_str.len() };
-
-    // Args.
-    let (one_line_budget, multi_line_budget, mut arg_indent) = compute_budgets_for_args(
-        context,
-        &result,
-        indent,
-        ret_str_len,
-        newline_brace,
-        has_body,
-        multi_line_ret_str,
-    )?;
-
-    debug!(
-        "rewrite_fn_base: one_line_budget: {}, multi_line_budget: {}, arg_indent: {:?}",
-        one_line_budget, multi_line_budget, arg_indent
-    );
-
-    // Check if vertical layout was forced.
-    if one_line_budget == 0 {
-        if snuggle_angle_bracket {
-            result.push('(');
-        } else {
-            result.push_str("(");
-            if context.config.indent_style() == IndentStyle::Visual {
-                result.push('\n');
-                result.push_str(&arg_indent.to_string(context.config));
-            }
-        }
-    } else {
-        result.push('(');
-    }
-    if context.config.spaces_within_parens_and_brackets() && !fd.inputs.is_empty()
-        && result.ends_with('(')
-    {
-        result.push(' ')
-    }
-
-    // Skip `pub(crate)`.
-    let lo_after_visibility = get_bytepos_after_visibility(context, &fn_sig.visibility, span, ")");
-    // A conservative estimation, to goal is to be over all parens in generics
-    let args_start = fn_sig
-        .generics
-        .params
-        .iter()
-        .last()
-        .map_or(lo_after_visibility, |param| param.span().hi());
-    let args_end = if fd.inputs.is_empty() {
-        context
-            .codemap
-            .span_after(mk_sp(args_start, span.hi()), ")")
-    } else {
-        let last_span = mk_sp(fd.inputs[fd.inputs.len() - 1].span().hi(), span.hi());
-        context.codemap.span_after(last_span, ")")
-    };
-    let args_span = mk_sp(
-        context
-            .codemap
-            .span_after(mk_sp(args_start, span.hi()), "("),
-        args_end,
-    );
-    let arg_str = rewrite_args(
-        context,
-        &fd.inputs,
-        fd.get_self().as_ref(),
-        one_line_budget,
-        multi_line_budget,
-        indent,
-        arg_indent,
-        args_span,
-        fd.variadic,
-        generics_str.contains('\n'),
-    )?;
-
-    let put_args_in_block = match context.config.indent_style() {
-        IndentStyle::Block => arg_str.contains('\n') || arg_str.len() > one_line_budget,
-        _ => false,
-    } && !fd.inputs.is_empty();
-
-    let mut args_last_line_contains_comment = false;
-    if put_args_in_block {
-        arg_indent = indent.block_indent(context.config);
-        result.push('\n');
-        result.push_str(&arg_indent.to_string(context.config));
-        result.push_str(&arg_str);
-        result.push('\n');
-        result.push_str(&indent.to_string(context.config));
-        result.push(')');
-    } else {
-        result.push_str(&arg_str);
-        let used_width = last_line_used_width(&result, indent.width()) + first_line_width(&ret_str);
-        // Put the closing brace on the next line if it overflows the max width.
-        // 1 = `)`
-        if fd.inputs.is_empty() && used_width + 1 > context.config.max_width() {
-            result.push('\n');
-        }
-        if context.config.spaces_within_parens_and_brackets() && !fd.inputs.is_empty() {
-            result.push(' ')
-        }
-        // If the last line of args contains comment, we cannot put the closing paren
-        // on the same line.
-        if arg_str
-            .lines()
-            .last()
-            .map_or(false, |last_line| last_line.contains("//"))
-        {
-            args_last_line_contains_comment = true;
-            result.push('\n');
-            result.push_str(&arg_indent.to_string(context.config));
-        }
-        result.push(')');
-    }
-
-    // Return type.
-    if let ast::FunctionRetTy::Ty(..) = fd.output {
-        let ret_should_indent = match context.config.indent_style() {
-            // If our args are block layout then we surely must have space.
-            IndentStyle::Block if put_args_in_block || fd.inputs.is_empty() => false,
-            _ if args_last_line_contains_comment => false,
-            _ if result.contains('\n') || multi_line_ret_str => true,
-            _ => {
-                // If the return type would push over the max width, then put the return type on
-                // a new line. With the +1 for the signature length an additional space between
-                // the closing parenthesis of the argument and the arrow '->' is considered.
-                let mut sig_length = result.len() + indent.width() + ret_str_len + 1;
-
-                // If there is no where clause, take into account the space after the return type
-                // and the brace.
-                if where_clause.predicates.is_empty() {
-                    sig_length += 2;
-                }
-
-                sig_length > context.config.max_width()
-            }
-        };
-        let ret_indent = if ret_should_indent {
-            let indent = if arg_str.is_empty() {
-                // Aligning with non-existent args looks silly.
-                force_new_line_for_brace = true;
-                indent + 4
-            } else {
-                // FIXME: we might want to check that using the arg indent
-                // doesn't blow our budget, and if it does, then fallback to
-                // the where clause indent.
-                arg_indent
-            };
-
-            result.push('\n');
-            result.push_str(&indent.to_string(context.config));
-            indent
-        } else {
-            result.push(' ');
-            Indent::new(indent.block_indent, last_line_width(&result))
-        };
-
-        if multi_line_ret_str || ret_should_indent {
-            // Now that we know the proper indent and width, we need to
-            // re-layout the return type.
-            let ret_str = fd.output
-                .rewrite(context, Shape::indented(ret_indent, context.config))?;
-            result.push_str(&ret_str);
-        } else {
-            result.push_str(&ret_str);
-        }
-
-        // Comment between return type and the end of the decl.
-        let snippet_lo = fd.output.span().hi();
-        if where_clause.predicates.is_empty() {
-            let snippet_hi = span.hi();
-            let snippet = context.snippet(mk_sp(snippet_lo, snippet_hi));
-            // Try to preserve the layout of the original snippet.
-            let original_starts_with_newline = snippet
-                .find(|c| c != ' ')
-                .map_or(false, |i| starts_with_newline(&snippet[i..]));
-            let original_ends_with_newline = snippet
-                .rfind(|c| c != ' ')
-                .map_or(false, |i| snippet[i..].ends_with('\n'));
-            let snippet = snippet.trim();
-            if !snippet.is_empty() {
-                result.push(if original_starts_with_newline {
-                    '\n'
-                } else {
-                    ' '
-                });
-                result.push_str(snippet);
-                if original_ends_with_newline {
-                    force_new_line_for_brace = true;
-                }
-            }
-        }
-    }
-
-    let pos_before_where = match fd.output {
-        ast::FunctionRetTy::Default(..) => args_span.hi(),
-        ast::FunctionRetTy::Ty(ref ty) => ty.span.hi(),
-    };
-
-    let is_args_multi_lined = arg_str.contains('\n');
-
-    let option = WhereClauseOption::new(!has_body, put_args_in_block && ret_str.is_empty());
-    let where_clause_str = rewrite_where_clause(
-        context,
-        where_clause,
-        context.config.brace_style(),
-        Shape::indented(indent, context.config),
-        Density::Tall,
-        "{",
-        Some(span.hi()),
-        pos_before_where,
-        option,
-        is_args_multi_lined,
-    )?;
-    // If there are neither where clause nor return type, we may be missing comments between
-    // args and `{`.
-    if where_clause_str.is_empty() {
-        if let ast::FunctionRetTy::Default(ret_span) = fd.output {
-            match recover_missing_comment_in_span(
-                mk_sp(args_span.hi(), ret_span.hi()),
-                shape,
-                context,
-                last_line_width(&result),
-            ) {
-                Some(ref missing_comment) if !missing_comment.is_empty() => {
-                    result.push_str(missing_comment);
-                    force_new_line_for_brace = true;
-                }
-                _ => (),
-            }
-        }
-    }
-
-    result.push_str(&where_clause_str);
-
-    force_new_line_for_brace |= last_line_contains_single_line_comment(&result);
-    force_new_line_for_brace |= is_args_multi_lined && context.config.where_single_line();
-    Some((result, force_new_line_for_brace))
-}
-
-#[derive(Copy, Clone)]
-struct WhereClauseOption {
-    suppress_comma: bool, // Force no trailing comma
-    snuggle: bool,        // Do not insert newline before `where`
-    compress_where: bool, // Try single line where clause instead of vertical layout
-}
-
-impl WhereClauseOption {
-    pub fn new(suppress_comma: bool, snuggle: bool) -> WhereClauseOption {
-        WhereClauseOption {
-            suppress_comma,
-            snuggle,
-            compress_where: false,
-        }
-    }
-
-    pub fn snuggled(current: &str) -> WhereClauseOption {
-        WhereClauseOption {
-            suppress_comma: false,
-            snuggle: trimmed_last_line_width(current) == 1,
-            compress_where: false,
-        }
-    }
-}
-
-fn rewrite_args(
-    context: &RewriteContext,
-    args: &[ast::Arg],
-    explicit_self: Option<&ast::ExplicitSelf>,
-    one_line_budget: usize,
-    multi_line_budget: usize,
-    indent: Indent,
-    arg_indent: Indent,
-    span: Span,
-    variadic: bool,
-    generics_str_contains_newline: bool,
-) -> Option<String> {
-    let mut arg_item_strs = args.iter()
-        .map(|arg| arg.rewrite(context, Shape::legacy(multi_line_budget, arg_indent)))
-        .collect::<Option<Vec<_>>>()?;
-
-    // Account for sugary self.
-    // FIXME: the comment for the self argument is dropped. This is blocked
-    // on rust issue #27522.
-    let min_args = explicit_self
-        .and_then(|explicit_self| rewrite_explicit_self(explicit_self, args, context))
-        .map_or(1, |self_str| {
-            arg_item_strs[0] = self_str;
-            2
-        });
-
-    // Comments between args.
-    let mut arg_items = Vec::new();
-    if min_args == 2 {
-        arg_items.push(ListItem::from_str(""));
-    }
-
-    // FIXME(#21): if there are no args, there might still be a comment, but
-    // without spans for the comment or parens, there is no chance of
-    // getting it right. You also don't get to put a comment on self, unless
-    // it is explicit.
-    if args.len() >= min_args || variadic {
-        let comment_span_start = if min_args == 2 {
-            let second_arg_start = if arg_has_pattern(&args[1]) {
-                args[1].pat.span.lo()
-            } else {
-                args[1].ty.span.lo()
-            };
-            let reduced_span = mk_sp(span.lo(), second_arg_start);
-
-            context.codemap.span_after_last(reduced_span, ",")
-        } else {
-            span.lo()
-        };
-
-        enum ArgumentKind<'a> {
-            Regular(&'a ast::Arg),
-            Variadic(BytePos),
-        }
-
-        let variadic_arg = if variadic {
-            let variadic_span = mk_sp(args.last().unwrap().ty.span.hi(), span.hi());
-            let variadic_start = context.codemap.span_after(variadic_span, "...") - BytePos(3);
-            Some(ArgumentKind::Variadic(variadic_start))
-        } else {
-            None
-        };
-
-        let more_items = itemize_list(
-            context.codemap,
-            args[min_args - 1..]
-                .iter()
-                .map(ArgumentKind::Regular)
-                .chain(variadic_arg),
-            ")",
-            ",",
-            |arg| match *arg {
-                ArgumentKind::Regular(arg) => span_lo_for_arg(arg),
-                ArgumentKind::Variadic(start) => start,
-            },
-            |arg| match *arg {
-                ArgumentKind::Regular(arg) => arg.ty.span.hi(),
-                ArgumentKind::Variadic(start) => start + BytePos(3),
-            },
-            |arg| match *arg {
-                ArgumentKind::Regular(..) => None,
-                ArgumentKind::Variadic(..) => Some("...".to_owned()),
-            },
-            comment_span_start,
-            span.hi(),
-            false,
-        );
-
-        arg_items.extend(more_items);
-    }
-
-    let fits_in_one_line = !generics_str_contains_newline
-        && (arg_items.is_empty()
-            || arg_items.len() == 1 && arg_item_strs[0].len() <= one_line_budget);
-
-    for (item, arg) in arg_items.iter_mut().zip(arg_item_strs) {
-        item.item = Some(arg);
-    }
-
-    let last_line_ends_with_comment = arg_items
-        .iter()
-        .last()
-        .and_then(|item| item.post_comment.as_ref())
-        .map_or(false, |s| s.trim().starts_with("//"));
-
-    let (indent, trailing_comma) = match context.config.indent_style() {
-        IndentStyle::Block if fits_in_one_line => {
-            (indent.block_indent(context.config), SeparatorTactic::Never)
-        }
-        IndentStyle::Block => (
-            indent.block_indent(context.config),
-            context.config.trailing_comma(),
-        ),
-        IndentStyle::Visual if last_line_ends_with_comment => {
-            (arg_indent, context.config.trailing_comma())
-        }
-        IndentStyle::Visual => (arg_indent, SeparatorTactic::Never),
-    };
-
-    let tactic = definitive_tactic(
-        &arg_items,
-        context.config.fn_args_density().to_list_tactic(),
-        Separator::Comma,
-        one_line_budget,
-    );
-    let budget = match tactic {
-        DefinitiveListTactic::Horizontal => one_line_budget,
-        _ => multi_line_budget,
-    };
-
-    debug!("rewrite_args: budget: {}, tactic: {:?}", budget, tactic);
-
-    let fmt = ListFormatting {
-        tactic,
-        separator: ",",
-        trailing_separator: if variadic {
-            SeparatorTactic::Never
-        } else {
-            trailing_comma
-        },
-        separator_place: SeparatorPlace::Back,
-        shape: Shape::legacy(budget, indent),
-        ends_with_newline: tactic.ends_with_newline(context.config.indent_style()),
-        preserve_newline: true,
-        config: context.config,
-    };
-
-    write_list(&arg_items, &fmt)
-}
-
-fn arg_has_pattern(arg: &ast::Arg) -> bool {
-    if let ast::PatKind::Ident(_, ident, _) = arg.pat.node {
-        ident.node != symbol::keywords::Invalid.ident()
-    } else {
-        true
-    }
-}
-
-fn compute_budgets_for_args(
-    context: &RewriteContext,
-    result: &str,
-    indent: Indent,
-    ret_str_len: usize,
-    newline_brace: bool,
-    has_braces: bool,
-    force_vertical_layout: bool,
-) -> Option<((usize, usize, Indent))> {
-    debug!(
-        "compute_budgets_for_args {} {:?}, {}, {}",
-        result.len(),
-        indent,
-        ret_str_len,
-        newline_brace
-    );
-    // Try keeping everything on the same line.
-    if !result.contains('\n') && !force_vertical_layout {
-        // 2 = `()`, 3 = `() `, space is before ret_string.
-        let overhead = if ret_str_len == 0 { 2 } else { 3 };
-        let mut used_space = indent.width() + result.len() + ret_str_len + overhead;
-        if has_braces {
-            if !newline_brace {
-                // 2 = `{}`
-                used_space += 2;
-            }
-        } else {
-            // 1 = `;`
-            used_space += 1;
-        }
-        let one_line_budget = context.budget(used_space);
-
-        if one_line_budget > 0 {
-            // 4 = "() {".len()
-            let (indent, multi_line_budget) = match context.config.indent_style() {
-                IndentStyle::Block => {
-                    let indent = indent.block_indent(context.config);
-                    (indent, context.budget(indent.width() + 1))
-                }
-                IndentStyle::Visual => {
-                    let indent = indent + result.len() + 1;
-                    let multi_line_overhead = indent.width() + if newline_brace { 2 } else { 4 };
-                    (indent, context.budget(multi_line_overhead))
-                }
-            };
-
-            return Some((one_line_budget, multi_line_budget, indent));
-        }
-    }
-
-    // Didn't work. we must force vertical layout and put args on a newline.
-    let new_indent = indent.block_indent(context.config);
-    let used_space = match context.config.indent_style() {
-        // 1 = `,`
-        IndentStyle::Block => new_indent.width() + 1,
-        // Account for `)` and possibly ` {`.
-        IndentStyle::Visual => new_indent.width() + if ret_str_len == 0 { 1 } else { 3 },
-    };
-    Some((0, context.budget(used_space), new_indent))
-}
-
-fn newline_for_brace(config: &Config, where_clause: &ast::WhereClause) -> bool {
-    let predicate_count = where_clause.predicates.len();
-
-    if config.where_single_line() && predicate_count == 1 {
-        return false;
-    }
-    let brace_style = config.brace_style();
-
-    brace_style == BraceStyle::AlwaysNextLine
-        || (brace_style == BraceStyle::SameLineWhere && predicate_count > 0)
-}
-
-fn rewrite_generics(
-    context: &RewriteContext,
-    generics: &ast::Generics,
-    shape: Shape,
-    span: Span,
-) -> Option<String> {
-    let g_shape = generics_shape_from_config(context.config, shape, 0)?;
-    let one_line_width = shape.width.checked_sub(2).unwrap_or(0);
-    rewrite_generics_inner(context, generics, g_shape, one_line_width, span)
-        .or_else(|| rewrite_generics_inner(context, generics, g_shape, 0, span))
-}
-
-fn rewrite_generics_inner(
-    context: &RewriteContext,
-    generics: &ast::Generics,
-    shape: Shape,
-    one_line_width: usize,
-    span: Span,
-) -> Option<String> {
-    // FIXME: convert bounds to where clauses where they get too big or if
-    // there is a where clause at all.
-
-    if generics.params.is_empty() {
-        return Some(String::new());
-    }
-
-    let items = itemize_list(
-        context.codemap,
-        generics.params.iter(),
-        ">",
-        ",",
-        |arg| arg.span().lo(),
-        |arg| arg.span().hi(),
-        |arg| arg.rewrite(context, shape),
-        context.codemap.span_after(span, "<"),
-        span.hi(),
-        false,
-    );
-    format_generics_item_list(context, items, shape, one_line_width)
-}
-
-pub fn generics_shape_from_config(config: &Config, shape: Shape, offset: usize) -> Option<Shape> {
-    match config.indent_style() {
-        IndentStyle::Visual => shape.visual_indent(1 + offset).sub_width(offset + 2),
-        IndentStyle::Block => {
-            // 1 = ","
-            shape
-                .block()
-                .block_indent(config.tab_spaces())
-                .with_max_width(config)
-                .sub_width(1)
-        }
-    }
-}
-
-pub fn format_generics_item_list<I>(
-    context: &RewriteContext,
-    items: I,
-    shape: Shape,
-    one_line_budget: usize,
-) -> Option<String>
-where
-    I: Iterator<Item = ListItem>,
-{
-    let item_vec = items.collect::<Vec<_>>();
-
-    let tactic = definitive_tactic(
-        &item_vec,
-        ListTactic::HorizontalVertical,
-        Separator::Comma,
-        one_line_budget,
-    );
-    let fmt = ListFormatting {
-        tactic,
-        separator: ",",
-        trailing_separator: if context.config.indent_style() == IndentStyle::Visual {
-            SeparatorTactic::Never
-        } else {
-            context.config.trailing_comma()
-        },
-        separator_place: SeparatorPlace::Back,
-        shape,
-        ends_with_newline: tactic.ends_with_newline(context.config.indent_style()),
-        preserve_newline: true,
-        config: context.config,
-    };
-
-    let list_str = write_list(&item_vec, &fmt)?;
-
-    Some(wrap_generics_with_angle_brackets(
-        context,
-        &list_str,
-        shape.indent,
-    ))
-}
-
-pub fn wrap_generics_with_angle_brackets(
-    context: &RewriteContext,
-    list_str: &str,
-    list_offset: Indent,
-) -> String {
-    if context.config.indent_style() == IndentStyle::Block
-        && (list_str.contains('\n') || list_str.ends_with(','))
-    {
-        format!(
-            "<\n{}{}\n{}>",
-            list_offset.to_string(context.config),
-            list_str,
-            list_offset
-                .block_unindent(context.config)
-                .to_string(context.config)
-        )
-    } else if context.config.spaces_within_parens_and_brackets() {
-        format!("< {} >", list_str)
-    } else {
-        format!("<{}>", list_str)
-    }
-}
-
-fn rewrite_trait_bounds(
-    context: &RewriteContext,
-    bounds: &[ast::TyParamBound],
-    shape: Shape,
-) -> Option<String> {
-    if bounds.is_empty() {
-        return Some(String::new());
-    }
-    let bound_str = bounds
-        .iter()
-        .map(|ty_bound| ty_bound.rewrite(context, shape))
-        .collect::<Option<Vec<_>>>()?;
-    Some(format!(": {}", join_bounds(context, shape, &bound_str)))
-}
-
-fn rewrite_where_clause_rfc_style(
-    context: &RewriteContext,
-    where_clause: &ast::WhereClause,
-    shape: Shape,
-    terminator: &str,
-    span_end: Option<BytePos>,
-    span_end_before_where: BytePos,
-    where_clause_option: WhereClauseOption,
-    is_args_multi_line: bool,
-) -> Option<String> {
-    let block_shape = shape.block().with_max_width(context.config);
-
-    let (span_before, span_after) =
-        missing_span_before_after_where(span_end_before_where, where_clause);
-    let (comment_before, comment_after) =
-        rewrite_comments_before_after_where(context, span_before, span_after, shape)?;
-
-    let starting_newline = if where_clause_option.snuggle && comment_before.is_empty() {
-        " ".to_owned()
-    } else {
-        "\n".to_owned() + &block_shape.indent.to_string(context.config)
-    };
-
-    let clause_shape = block_shape.block_left(context.config.tab_spaces())?;
-    // 1 = `,`
-    let clause_shape = clause_shape.sub_width(1)?;
-    // each clause on one line, trailing comma (except if suppress_comma)
-    let span_start = where_clause.predicates[0].span().lo();
-    // If we don't have the start of the next span, then use the end of the
-    // predicates, but that means we miss comments.
-    let len = where_clause.predicates.len();
-    let end_of_preds = where_clause.predicates[len - 1].span().hi();
-    let span_end = span_end.unwrap_or(end_of_preds);
-    let items = itemize_list(
-        context.codemap,
-        where_clause.predicates.iter(),
-        terminator,
-        ",",
-        |pred| pred.span().lo(),
-        |pred| pred.span().hi(),
-        |pred| pred.rewrite(context, clause_shape),
-        span_start,
-        span_end,
-        false,
-    );
-    let where_single_line = context.config.where_single_line() && len == 1 && !is_args_multi_line;
-    let comma_tactic = if where_clause_option.suppress_comma || where_single_line {
-        SeparatorTactic::Never
-    } else {
-        context.config.trailing_comma()
-    };
-
-    // shape should be vertical only and only if we have `where_single_line` option enabled
-    // and the number of items of the where clause is equal to 1
-    let shape_tactic = if where_single_line {
-        DefinitiveListTactic::Horizontal
-    } else {
-        DefinitiveListTactic::Vertical
-    };
-
-    let fmt = ListFormatting {
-        tactic: shape_tactic,
-        separator: ",",
-        trailing_separator: comma_tactic,
-        separator_place: SeparatorPlace::Back,
-        shape: clause_shape,
-        ends_with_newline: true,
-        preserve_newline: true,
-        config: context.config,
-    };
-    let preds_str = write_list(&items.collect::<Vec<_>>(), &fmt)?;
-
-    let comment_separator = |comment: &str, shape: Shape| {
-        if comment.is_empty() {
-            String::new()
-        } else {
-            format!("\n{}", shape.indent.to_string(context.config))
-        }
-    };
-    let newline_before_where = comment_separator(&comment_before, shape);
-    let newline_after_where = comment_separator(&comment_after, clause_shape);
-
-    // 6 = `where `
-    let clause_sep = if where_clause_option.compress_where && comment_before.is_empty()
-        && comment_after.is_empty() && !preds_str.contains('\n')
-        && 6 + preds_str.len() <= shape.width || where_single_line
-    {
-        String::from(" ")
-    } else {
-        format!("\n{}", clause_shape.indent.to_string(context.config))
-    };
-    Some(format!(
-        "{}{}{}where{}{}{}{}",
-        starting_newline,
-        comment_before,
-        newline_before_where,
-        newline_after_where,
-        comment_after,
-        clause_sep,
-        preds_str
-    ))
-}
-
-fn rewrite_where_clause(
-    context: &RewriteContext,
-    where_clause: &ast::WhereClause,
-    brace_style: BraceStyle,
-    shape: Shape,
-    density: Density,
-    terminator: &str,
-    span_end: Option<BytePos>,
-    span_end_before_where: BytePos,
-    where_clause_option: WhereClauseOption,
-    is_args_multi_line: bool,
-) -> Option<String> {
-    if where_clause.predicates.is_empty() {
-        return Some(String::new());
-    }
-
-    if context.config.indent_style() == IndentStyle::Block {
-        return rewrite_where_clause_rfc_style(
-            context,
-            where_clause,
-            shape,
-            terminator,
-            span_end,
-            span_end_before_where,
-            where_clause_option,
-            is_args_multi_line,
-        );
-    }
-
-    let extra_indent = Indent::new(context.config.tab_spaces(), 0);
-
-    let offset = match context.config.indent_style() {
-        IndentStyle::Block => shape.indent + extra_indent.block_indent(context.config),
-        // 6 = "where ".len()
-        IndentStyle::Visual => shape.indent + extra_indent + 6,
-    };
-    // FIXME: if indent_style != Visual, then the budgets below might
-    // be out by a char or two.
-
-    let budget = context.config.max_width() - offset.width();
-    let span_start = where_clause.predicates[0].span().lo();
-    // If we don't have the start of the next span, then use the end of the
-    // predicates, but that means we miss comments.
-    let len = where_clause.predicates.len();
-    let end_of_preds = where_clause.predicates[len - 1].span().hi();
-    let span_end = span_end.unwrap_or(end_of_preds);
-    let items = itemize_list(
-        context.codemap,
-        where_clause.predicates.iter(),
-        terminator,
-        ",",
-        |pred| pred.span().lo(),
-        |pred| pred.span().hi(),
-        |pred| pred.rewrite(context, Shape::legacy(budget, offset)),
-        span_start,
-        span_end,
-        false,
-    );
-    let item_vec = items.collect::<Vec<_>>();
-    // FIXME: we don't need to collect here
-    let tactic = definitive_tactic(&item_vec, ListTactic::Vertical, Separator::Comma, budget);
-
-    let mut comma_tactic = context.config.trailing_comma();
-    // Kind of a hack because we don't usually have trailing commas in where clauses.
-    if comma_tactic == SeparatorTactic::Vertical || where_clause_option.suppress_comma {
-        comma_tactic = SeparatorTactic::Never;
-    }
-
-    let fmt = ListFormatting {
-        tactic,
-        separator: ",",
-        trailing_separator: comma_tactic,
-        separator_place: SeparatorPlace::Back,
-        shape: Shape::legacy(budget, offset),
-        ends_with_newline: tactic.ends_with_newline(context.config.indent_style()),
-        preserve_newline: true,
-        config: context.config,
-    };
-    let preds_str = write_list(&item_vec, &fmt)?;
-
-    let end_length = if terminator == "{" {
-        // If the brace is on the next line we don't need to count it otherwise it needs two
-        // characters " {"
-        match brace_style {
-            BraceStyle::AlwaysNextLine | BraceStyle::SameLineWhere => 0,
-            BraceStyle::PreferSameLine => 2,
-        }
-    } else if terminator == "=" {
-        2
-    } else {
-        terminator.len()
-    };
-    if density == Density::Tall || preds_str.contains('\n')
-        || shape.indent.width() + " where ".len() + preds_str.len() + end_length > shape.width
-    {
-        Some(format!(
-            "\n{}where {}",
-            (shape.indent + extra_indent).to_string(context.config),
-            preds_str
-        ))
-    } else {
-        Some(format!(" where {}", preds_str))
-    }
-}
-
-fn missing_span_before_after_where(
-    before_item_span_end: BytePos,
-    where_clause: &ast::WhereClause,
-) -> (Span, Span) {
-    let missing_span_before = mk_sp(before_item_span_end, where_clause.span.lo());
-    // 5 = `where`
-    let pos_after_where = where_clause.span.lo() + BytePos(5);
-    let missing_span_after = mk_sp(pos_after_where, where_clause.predicates[0].span().lo());
-    (missing_span_before, missing_span_after)
-}
-
-fn rewrite_comments_before_after_where(
-    context: &RewriteContext,
-    span_before_where: Span,
-    span_after_where: Span,
-    shape: Shape,
-) -> Option<(String, String)> {
-    let before_comment = rewrite_missing_comment(span_before_where, shape, context)?;
-    let after_comment = rewrite_missing_comment(
-        span_after_where,
-        shape.block_indent(context.config.tab_spaces()),
-        context,
-    )?;
-    Some((before_comment, after_comment))
-}
-
-fn format_header(item_name: &str, ident: ast::Ident, vis: &ast::Visibility) -> String {
-    format!("{}{}{}", format_visibility(vis), item_name, ident)
-}
-
-#[derive(PartialEq, Eq, Clone, Copy)]
-enum BracePos {
-    None,
-    Auto,
-    ForceSameLine,
-}
-
-fn format_generics(
-    context: &RewriteContext,
-    generics: &ast::Generics,
-    brace_style: BraceStyle,
-    brace_pos: BracePos,
-    offset: Indent,
-    span: Span,
-    used_width: usize,
-) -> Option<String> {
-    let shape = Shape::legacy(context.budget(used_width + offset.width()), offset);
-    let mut result = rewrite_generics(context, generics, shape, span)?;
-
-    let same_line_brace = if !generics.where_clause.predicates.is_empty() || result.contains('\n') {
-        let budget = context.budget(last_line_used_width(&result, offset.width()));
-        let mut option = WhereClauseOption::snuggled(&result);
-        if brace_pos == BracePos::None {
-            option.suppress_comma = true;
-        }
-        // If the generics are not parameterized then generics.span.hi() == 0,
-        // so we use span.lo(), which is the position after `struct Foo`.
-        let span_end_before_where = if generics.is_parameterized() {
-            generics.span.hi()
-        } else {
-            span.lo()
-        };
-        let where_clause_str = rewrite_where_clause(
-            context,
-            &generics.where_clause,
-            brace_style,
-            Shape::legacy(budget, offset.block_only()),
-            Density::Tall,
-            "{",
-            Some(span.hi()),
-            span_end_before_where,
-            option,
-            false,
-        )?;
-        result.push_str(&where_clause_str);
-        brace_pos == BracePos::ForceSameLine || brace_style == BraceStyle::PreferSameLine
-            || (generics.where_clause.predicates.is_empty()
-                && trimmed_last_line_width(&result) == 1)
-    } else {
-        brace_pos == BracePos::ForceSameLine || trimmed_last_line_width(&result) == 1
-            || brace_style != BraceStyle::AlwaysNextLine
-    };
-    if brace_pos == BracePos::None {
-        return Some(result);
-    }
-    let total_used_width = last_line_used_width(&result, used_width);
-    let remaining_budget = context.budget(total_used_width);
-    // If the same line brace if forced, it indicates that we are rewriting an item with empty body,
-    // and hence we take the closer into account as well for one line budget.
-    // We assume that the closer has the same length as the opener.
-    let overhead = if brace_pos == BracePos::ForceSameLine {
-        // 3 = ` {}`
-        3
-    } else {
-        // 2 = ` {`
-        2
-    };
-    let forbid_same_line_brace = overhead > remaining_budget;
-    if !forbid_same_line_brace && same_line_brace {
-        result.push(' ');
-    } else {
-        result.push('\n');
-        result.push_str(&offset.block_only().to_string(context.config));
-    }
-    result.push('{');
-
-    Some(result)
-}
-
-impl Rewrite for ast::ForeignItem {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        let attrs_str = 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 = match self.node {
-            ast::ForeignItemKind::Fn(ref fn_decl, ref generics) => {
-                rewrite_fn_base(
-                    context,
-                    shape.indent,
-                    self.ident,
-                    &FnSig::new(fn_decl, generics, self.vis.clone()),
-                    span,
-                    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 = 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)
-                })
-            }
-            ast::ForeignItemKind::Ty => {
-                let vis = format_visibility(&self.vis);
-                Some(format!("{}type {};", vis, self.ident))
-            }
-        }?;
-
-        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,
-        )
-    }
-}
-
-impl Rewrite for ast::GenericParam {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        match *self {
-            ast::GenericParam::Lifetime(ref lifetime_def) => lifetime_def.rewrite(context, shape),
-            ast::GenericParam::Type(ref ty) => ty.rewrite(context, shape),
-        }
-    }
-}
diff --git a/src/lib.rs b/src/lib.rs
deleted file mode 100644
index 6aca11ab3ee..00000000000
--- a/src/lib.rs
+++ /dev/null
@@ -1,828 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![feature(decl_macro)]
-#![feature(match_default_bindings)]
-#![feature(type_ascription)]
-
-#[macro_use]
-extern crate derive_new;
-extern crate diff;
-#[macro_use]
-extern crate log;
-extern crate regex;
-extern crate rustc_errors as errors;
-extern crate serde;
-#[macro_use]
-extern crate serde_derive;
-extern crate serde_json;
-extern crate syntax;
-extern crate term;
-extern crate unicode_segmentation;
-
-use std::collections::HashMap;
-use std::fmt;
-use std::io::{self, stdout, Write};
-use std::iter::repeat;
-use std::path::PathBuf;
-use std::rc::Rc;
-use std::time::Duration;
-
-use errors::{DiagnosticBuilder, Handler};
-use errors::emitter::{ColorConfig, EmitterWriter};
-use syntax::ast;
-use syntax::codemap::{CodeMap, FilePathMapping};
-pub use syntax::codemap::FileName;
-use syntax::parse::{self, ParseSess};
-
-use checkstyle::{output_footer, output_header};
-use comment::{CharClasses, FullCodeCharKind};
-pub use config::Config;
-use filemap::FileMap;
-use issues::{BadIssueSeeker, Issue};
-use shape::Indent;
-use utils::use_colored_tty;
-use visitor::{FmtVisitor, SnippetProvider};
-
-pub use self::summary::Summary;
-
-#[macro_use]
-mod utils;
-mod chains;
-mod checkstyle;
-mod closures;
-pub mod codemap;
-mod comment;
-pub mod config;
-mod expr;
-pub mod file_lines;
-pub mod filemap;
-mod imports;
-mod issues;
-mod items;
-mod lists;
-mod macros;
-mod missed_spans;
-pub mod modules;
-mod patterns;
-mod rewrite;
-pub mod rustfmt_diff;
-mod shape;
-mod spanned;
-mod string;
-mod summary;
-mod types;
-mod vertical;
-pub mod visitor;
-
-#[derive(Clone, Copy)]
-pub enum ErrorKind {
-    // Line has exceeded character limit (found, maximum)
-    LineOverflow(usize, usize),
-    // Line ends in whitespace
-    TrailingWhitespace,
-    // TO-DO or FIX-ME item without an issue number
-    BadIssue(Issue),
-}
-
-impl fmt::Display for ErrorKind {
-    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-        match *self {
-            ErrorKind::LineOverflow(found, maximum) => write!(
-                fmt,
-                "line exceeded maximum width (maximum: {}, found: {})",
-                maximum, found
-            ),
-            ErrorKind::TrailingWhitespace => write!(fmt, "left behind trailing whitespace"),
-            ErrorKind::BadIssue(issue) => write!(fmt, "found {}", issue),
-        }
-    }
-}
-
-// Formatting errors that are identified *after* rustfmt has run.
-pub struct FormattingError {
-    line: usize,
-    kind: ErrorKind,
-    is_comment: bool,
-    is_string: bool,
-    line_buffer: String,
-}
-
-impl FormattingError {
-    fn msg_prefix(&self) -> &str {
-        match self.kind {
-            ErrorKind::LineOverflow(..) | ErrorKind::TrailingWhitespace => "error:",
-            ErrorKind::BadIssue(_) => "WARNING:",
-        }
-    }
-
-    fn msg_suffix(&self) -> &str {
-        if self.is_comment || self.is_string {
-            "set `error_on_unformatted = false` to suppress \
-             the warning against comments or string literals\n"
-        } else {
-            ""
-        }
-    }
-
-    // (space, target)
-    pub fn format_len(&self) -> (usize, usize) {
-        match self.kind {
-            ErrorKind::LineOverflow(found, max) => (max, found - max),
-            ErrorKind::TrailingWhitespace => {
-                let trailing_ws_len = self.line_buffer
-                    .chars()
-                    .rev()
-                    .take_while(|c| c.is_whitespace())
-                    .count();
-                (self.line_buffer.len() - trailing_ws_len, trailing_ws_len)
-            }
-            _ => unreachable!(),
-        }
-    }
-}
-
-pub struct FormatReport {
-    // Maps stringified file paths to their associated formatting errors.
-    file_error_map: HashMap<FileName, Vec<FormattingError>>,
-}
-
-impl FormatReport {
-    fn new() -> FormatReport {
-        FormatReport {
-            file_error_map: HashMap::new(),
-        }
-    }
-
-    pub fn warning_count(&self) -> usize {
-        self.file_error_map
-            .iter()
-            .map(|(_, errors)| errors.len())
-            .sum()
-    }
-
-    pub fn has_warnings(&self) -> bool {
-        self.warning_count() > 0
-    }
-
-    pub fn print_warnings_fancy(
-        &self,
-        mut t: Box<term::Terminal<Output = io::Stderr>>,
-    ) -> Result<(), term::Error> {
-        for (file, errors) in &self.file_error_map {
-            for error in errors {
-                let prefix_space_len = error.line.to_string().len();
-                let prefix_spaces: String = repeat(" ").take(1 + prefix_space_len).collect();
-
-                // First line: the overview of error
-                t.fg(term::color::RED)?;
-                t.attr(term::Attr::Bold)?;
-                write!(t, "{} ", error.msg_prefix())?;
-                t.reset()?;
-                t.attr(term::Attr::Bold)?;
-                write!(t, "{}\n", error.kind)?;
-
-                // Second line: file info
-                write!(t, "{}--> ", &prefix_spaces[1..])?;
-                t.reset()?;
-                write!(t, "{}:{}\n", file, error.line)?;
-
-                // Third to fifth lines: show the line which triggered error, if available.
-                if !error.line_buffer.is_empty() {
-                    let (space_len, target_len) = error.format_len();
-                    t.attr(term::Attr::Bold)?;
-                    write!(t, "{}|\n{} | ", prefix_spaces, error.line)?;
-                    t.reset()?;
-                    write!(t, "{}\n", error.line_buffer)?;
-                    t.attr(term::Attr::Bold)?;
-                    write!(t, "{}| ", prefix_spaces)?;
-                    t.fg(term::color::RED)?;
-                    write!(t, "{}\n", target_str(space_len, target_len))?;
-                    t.reset()?;
-                }
-
-                // The last line: show note if available.
-                let msg_suffix = error.msg_suffix();
-                if !msg_suffix.is_empty() {
-                    t.attr(term::Attr::Bold)?;
-                    write!(t, "{}= note: ", prefix_spaces)?;
-                    t.reset()?;
-                    write!(t, "{}\n", error.msg_suffix())?;
-                } else {
-                    write!(t, "\n")?;
-                }
-                t.reset()?;
-            }
-        }
-
-        if !self.file_error_map.is_empty() {
-            t.attr(term::Attr::Bold)?;
-            write!(t, "warning: ")?;
-            t.reset()?;
-            write!(
-                t,
-                "rustfmt may have failed to format. See previous {} errors.\n\n",
-                self.warning_count(),
-            )?;
-        }
-
-        Ok(())
-    }
-}
-
-fn target_str(space_len: usize, target_len: usize) -> String {
-    let empty_line: String = repeat(" ").take(space_len).collect();
-    let overflowed: String = repeat("^").take(target_len).collect();
-    empty_line + &overflowed
-}
-
-impl fmt::Display for FormatReport {
-    // Prints all the formatting errors.
-    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-        for (file, errors) in &self.file_error_map {
-            for error in errors {
-                let prefix_space_len = error.line.to_string().len();
-                let prefix_spaces: String = repeat(" ").take(1 + prefix_space_len).collect();
-
-                let error_line_buffer = if error.line_buffer.is_empty() {
-                    String::from(" ")
-                } else {
-                    let (space_len, target_len) = error.format_len();
-                    format!(
-                        "{}|\n{} | {}\n{}| {}",
-                        prefix_spaces,
-                        error.line,
-                        error.line_buffer,
-                        prefix_spaces,
-                        target_str(space_len, target_len)
-                    )
-                };
-
-                let error_info = format!("{} {}", error.msg_prefix(), error.kind);
-                let file_info = format!("{}--> {}:{}", &prefix_spaces[1..], file, error.line);
-                let msg_suffix = error.msg_suffix();
-                let note = if msg_suffix.is_empty() {
-                    String::new()
-                } else {
-                    format!("{}note= ", prefix_spaces)
-                };
-
-                write!(
-                    fmt,
-                    "{}\n{}\n{}\n{}{}\n",
-                    error_info,
-                    file_info,
-                    error_line_buffer,
-                    note,
-                    error.msg_suffix()
-                )?;
-            }
-        }
-        if !self.file_error_map.is_empty() {
-            write!(
-                fmt,
-                "warning: rustfmt may have failed to format. See previous {} errors.\n",
-                self.warning_count(),
-            )?;
-        }
-        Ok(())
-    }
-}
-
-// Formatting which depends on the AST.
-fn format_ast<F>(
-    krate: &ast::Crate,
-    parse_session: &mut ParseSess,
-    main_file: &FileName,
-    config: &Config,
-    mut after_file: F,
-) -> Result<(FileMap, bool), io::Error>
-where
-    F: FnMut(&FileName, &mut String, &[(usize, usize)]) -> Result<bool, io::Error>,
-{
-    let mut result = FileMap::new();
-    // diff mode: check if any files are differing
-    let mut has_diff = false;
-
-    // We always skip children for the "Plain" write mode, since there is
-    // nothing to distinguish the nested module contents.
-    let skip_children = config.skip_children() || config.write_mode() == config::WriteMode::Plain;
-    for (path, module) in modules::list_files(krate, parse_session.codemap())? {
-        if skip_children && path != *main_file {
-            continue;
-        }
-        if config.verbose() {
-            println!("Formatting {}", path);
-        }
-        let filemap = parse_session
-            .codemap()
-            .lookup_char_pos(module.inner.lo())
-            .file;
-        let big_snippet = filemap.src.as_ref().unwrap();
-        let snippet_provider = SnippetProvider::new(filemap.start_pos, big_snippet);
-        let mut visitor = FmtVisitor::from_codemap(parse_session, config, &snippet_provider);
-        // Format inner attributes if available.
-        if !krate.attrs.is_empty() && path == *main_file {
-            visitor.skip_empty_lines(filemap.end_pos);
-            if visitor.visit_attrs(&krate.attrs, ast::AttrStyle::Inner) {
-                visitor.push_rewrite(module.inner, None);
-            } else {
-                visitor.format_separate_mod(module, &*filemap);
-            }
-        } else {
-            visitor.last_pos = filemap.start_pos;
-            visitor.skip_empty_lines(filemap.end_pos);
-            visitor.format_separate_mod(module, &*filemap);
-        };
-
-        assert_eq!(
-            visitor.line_number,
-            ::utils::count_newlines(&format!("{}", visitor.buffer))
-        );
-
-        let filename = path.clone();
-        has_diff |= match after_file(&filename, &mut visitor.buffer, &visitor.skipped_range) {
-            Ok(result) => result,
-            Err(e) => {
-                // Create a new error with path_str to help users see which files failed
-                let err_msg = format!("{}: {}", path, e);
-                return Err(io::Error::new(e.kind(), err_msg));
-            }
-        };
-
-        result.push((filename, visitor.buffer));
-    }
-
-    Ok((result, has_diff))
-}
-
-/// Returns true if the line with the given line number was skipped by `#[rustfmt_skip]`.
-fn is_skipped_line(line_number: usize, skipped_range: &[(usize, usize)]) -> bool {
-    skipped_range
-        .iter()
-        .any(|&(lo, hi)| lo <= line_number && line_number <= hi)
-}
-
-fn should_report_error(
-    config: &Config,
-    char_kind: FullCodeCharKind,
-    is_string: bool,
-    error_kind: ErrorKind,
-) -> bool {
-    let allow_error_report = if char_kind.is_comment() || is_string {
-        config.error_on_unformatted()
-    } else {
-        true
-    };
-
-    match error_kind {
-        ErrorKind::LineOverflow(..) => config.error_on_line_overflow() && allow_error_report,
-        ErrorKind::TrailingWhitespace => allow_error_report,
-        _ => true,
-    }
-}
-
-// Formatting done on a char by char or line by line basis.
-// FIXME(#209) warn on bad license
-// FIXME(#20) other stuff for parity with make tidy
-fn format_lines(
-    text: &mut String,
-    name: &FileName,
-    skipped_range: &[(usize, usize)],
-    config: &Config,
-    report: &mut FormatReport,
-) {
-    // Iterate over the chars in the file map.
-    let mut trims = vec![];
-    let mut last_wspace: Option<usize> = None;
-    let mut line_len = 0;
-    let mut cur_line = 1;
-    let mut newline_count = 0;
-    let mut errors = vec![];
-    let mut issue_seeker = BadIssueSeeker::new(config.report_todo(), config.report_fixme());
-    let mut line_buffer = String::with_capacity(config.max_width() * 2);
-    let mut is_string = false; // true if the current line contains a string literal.
-    let mut format_line = config.file_lines().contains_line(name, cur_line);
-
-    for (kind, (b, c)) in CharClasses::new(text.chars().enumerate()) {
-        if c == '\r' {
-            continue;
-        }
-
-        if format_line {
-            // Add warnings for bad todos/ fixmes
-            if let Some(issue) = issue_seeker.inspect(c) {
-                errors.push(FormattingError {
-                    line: cur_line,
-                    kind: ErrorKind::BadIssue(issue),
-                    is_comment: false,
-                    is_string: false,
-                    line_buffer: String::new(),
-                });
-            }
-        }
-
-        if c == '\n' {
-            if format_line {
-                // Check for (and record) trailing whitespace.
-                if let Some(..) = last_wspace {
-                    if should_report_error(config, kind, is_string, ErrorKind::TrailingWhitespace) {
-                        trims.push((cur_line, kind, line_buffer.clone()));
-                    }
-                    line_len -= 1;
-                }
-
-                // Check for any line width errors we couldn't correct.
-                let error_kind = ErrorKind::LineOverflow(line_len, config.max_width());
-                if line_len > config.max_width() && !is_skipped_line(cur_line, skipped_range)
-                    && should_report_error(config, kind, is_string, error_kind)
-                {
-                    errors.push(FormattingError {
-                        line: cur_line,
-                        kind: error_kind,
-                        is_comment: kind.is_comment(),
-                        is_string,
-                        line_buffer: line_buffer.clone(),
-                    });
-                }
-            }
-
-            line_len = 0;
-            cur_line += 1;
-            format_line = config.file_lines().contains_line(name, cur_line);
-            newline_count += 1;
-            last_wspace = None;
-            line_buffer.clear();
-            is_string = false;
-        } else {
-            newline_count = 0;
-            line_len += if c == '\t' { config.tab_spaces() } else { 1 };
-            if c.is_whitespace() {
-                if last_wspace.is_none() {
-                    last_wspace = Some(b);
-                }
-            } else {
-                last_wspace = None;
-            }
-            line_buffer.push(c);
-            if kind.is_string() {
-                is_string = true;
-            }
-        }
-    }
-
-    if newline_count > 1 {
-        debug!("track truncate: {} {}", text.len(), newline_count);
-        let line = text.len() - newline_count + 1;
-        text.truncate(line);
-    }
-
-    for &(l, kind, ref b) in &trims {
-        if !is_skipped_line(l, skipped_range) {
-            errors.push(FormattingError {
-                line: l,
-                kind: ErrorKind::TrailingWhitespace,
-                is_comment: kind.is_comment(),
-                is_string: kind.is_string(),
-                line_buffer: b.clone(),
-            });
-        }
-    }
-
-    report.file_error_map.insert(name.clone(), errors);
-}
-
-fn parse_input(
-    input: Input,
-    parse_session: &ParseSess,
-) -> Result<ast::Crate, Option<DiagnosticBuilder>> {
-    let result = match input {
-        Input::File(file) => {
-            let mut parser = parse::new_parser_from_file(parse_session, &file);
-            parser.cfg_mods = false;
-            parser.parse_crate_mod()
-        }
-        Input::Text(text) => {
-            let mut parser = parse::new_parser_from_source_str(
-                parse_session,
-                FileName::Custom("stdin".to_owned()),
-                text,
-            );
-            parser.cfg_mods = false;
-            parser.parse_crate_mod()
-        }
-    };
-
-    match result {
-        Ok(c) => {
-            if parse_session.span_diagnostic.has_errors() {
-                // Bail out if the parser recovered from an error.
-                Err(None)
-            } else {
-                Ok(c)
-            }
-        }
-        Err(e) => Err(Some(e)),
-    }
-}
-
-/// Format the given snippet. The snippet is expected to be *complete* code.
-/// When we cannot parse the given snippet, this function returns `None`.
-pub fn format_snippet(snippet: &str, config: &Config) -> Option<String> {
-    let mut out: Vec<u8> = Vec::with_capacity(snippet.len() * 2);
-    let input = Input::Text(snippet.into());
-    let mut config = config.clone();
-    config.set().write_mode(config::WriteMode::Plain);
-    config.set().hide_parse_errors(true);
-    match format_input(input, &config, Some(&mut out)) {
-        // `format_input()` returns an empty string on parsing error.
-        Ok(..) if out.is_empty() && !snippet.is_empty() => None,
-        Ok(..) => String::from_utf8(out).ok(),
-        Err(..) => None,
-    }
-}
-
-/// Format the given code block. Mainly targeted for code block in comment.
-/// The code block may be incomplete (i.e. parser may be unable to parse it).
-/// To avoid panic in parser, we wrap the code block with a dummy function.
-/// The returned code block does *not* end with newline.
-pub fn format_code_block(code_snippet: &str, config: &Config) -> Option<String> {
-    // Wrap the given code block with `fn main()` if it does not have one.
-    let fn_main_prefix = "fn main() {\n";
-    let snippet = fn_main_prefix.to_owned() + code_snippet + "\n}";
-
-    // Trim "fn main() {" on the first line and "}" on the last line,
-    // then unindent the whole code block.
-    format_snippet(&snippet, config).map(|s| {
-        // 2 = "}\n"
-        s[fn_main_prefix.len()..s.len().checked_sub(2).unwrap_or(0)]
-            .lines()
-            .map(|line| {
-                if line.len() > config.tab_spaces() {
-                    // Make sure that the line has leading whitespaces.
-                    let indent_str =
-                        Indent::from_width(config, config.tab_spaces()).to_string(config);
-                    if line.starts_with(indent_str.as_ref()) {
-                        let offset = if config.hard_tabs() {
-                            1
-                        } else {
-                            config.tab_spaces()
-                        };
-                        &line[offset..]
-                    } else {
-                        line
-                    }
-                } else {
-                    line
-                }
-            })
-            .collect::<Vec<_>>()
-            .join("\n")
-    })
-}
-
-pub fn format_input<T: Write>(
-    input: Input,
-    config: &Config,
-    mut out: Option<&mut T>,
-) -> Result<(Summary, FileMap, FormatReport), (io::Error, Summary)> {
-    let mut summary = Summary::default();
-    if config.disable_all_formatting() {
-        // When the input is from stdin, echo back the input.
-        if let Input::Text(ref buf) = input {
-            if let Err(e) = io::stdout().write_all(buf.as_bytes()) {
-                return Err((e, summary));
-            }
-        }
-        return Ok((summary, FileMap::new(), FormatReport::new()));
-    }
-    let codemap = Rc::new(CodeMap::new(FilePathMapping::empty()));
-
-    let tty_handler = if config.hide_parse_errors() {
-        let silent_emitter = Box::new(EmitterWriter::new(
-            Box::new(Vec::new()),
-            Some(codemap.clone()),
-            false,
-            false,
-        ));
-        Handler::with_emitter(true, false, silent_emitter)
-    } else {
-        let supports_color = term::stderr().map_or(false, |term| term.supports_color());
-        let color_cfg = if supports_color {
-            ColorConfig::Auto
-        } else {
-            ColorConfig::Never
-        };
-        Handler::with_tty_emitter(color_cfg, true, false, Some(codemap.clone()))
-    };
-    let mut parse_session = ParseSess::with_span_handler(tty_handler, codemap.clone());
-
-    let main_file = match input {
-        Input::File(ref file) => FileName::Real(file.clone()),
-        Input::Text(..) => FileName::Custom("stdin".to_owned()),
-    };
-
-    let krate = match parse_input(input, &parse_session) {
-        Ok(krate) => krate,
-        Err(diagnostic) => {
-            if let Some(mut diagnostic) = diagnostic {
-                diagnostic.emit();
-            }
-            summary.add_parsing_error();
-            return Ok((summary, FileMap::new(), FormatReport::new()));
-        }
-    };
-
-    summary.mark_parse_time();
-
-    if parse_session.span_diagnostic.has_errors() {
-        summary.add_parsing_error();
-    }
-
-    // Suppress error output after parsing.
-    let silent_emitter = Box::new(EmitterWriter::new(
-        Box::new(Vec::new()),
-        Some(codemap.clone()),
-        false,
-        false,
-    ));
-    parse_session.span_diagnostic = Handler::with_emitter(true, false, silent_emitter);
-
-    let mut report = FormatReport::new();
-
-    let format_result = format_ast(
-        &krate,
-        &mut parse_session,
-        &main_file,
-        config,
-        |file_name, file, skipped_range| {
-            // For some reason, the codemap does not include terminating
-            // newlines so we must add one on for each file. This is sad.
-            filemap::append_newline(file);
-
-            format_lines(file, file_name, skipped_range, config, &mut report);
-
-            if let Some(ref mut out) = out {
-                return filemap::write_file(file, file_name, out, config);
-            }
-            Ok(false)
-        },
-    );
-
-    summary.mark_format_time();
-
-    if config.verbose() {
-        fn duration_to_f32(d: Duration) -> f32 {
-            d.as_secs() as f32 + d.subsec_nanos() as f32 / 1_000_000_000f32
-        }
-
-        println!(
-            "Spent {0:.3} secs in the parsing phase, and {1:.3} secs in the formatting phase",
-            duration_to_f32(summary.get_parse_time().unwrap()),
-            duration_to_f32(summary.get_format_time().unwrap()),
-        );
-    }
-
-    match format_result {
-        Ok((file_map, has_diff)) => {
-            if report.has_warnings() {
-                summary.add_formatting_error();
-            }
-
-            if has_diff {
-                summary.add_diff();
-            }
-
-            Ok((summary, file_map, report))
-        }
-        Err(e) => Err((e, summary)),
-    }
-}
-
-#[derive(Debug)]
-pub enum Input {
-    File(PathBuf),
-    Text(String),
-}
-
-pub fn run(input: Input, config: &Config) -> Summary {
-    let out = &mut stdout();
-    output_header(out, config.write_mode()).ok();
-    match format_input(input, config, Some(out)) {
-        Ok((summary, _, report)) => {
-            output_footer(out, config.write_mode()).ok();
-
-            if report.has_warnings() {
-                match term::stderr() {
-                    Some(ref t)
-                        if use_colored_tty(config.color()) && t.supports_color()
-                            && t.supports_attr(term::Attr::Bold) =>
-                    {
-                        match report.print_warnings_fancy(term::stderr().unwrap()) {
-                            Ok(..) => (),
-                            Err(..) => panic!("Unable to write to stderr: {}", report),
-                        }
-                    }
-                    _ => msg!("{}", report),
-                }
-            }
-
-            summary
-        }
-        Err((msg, mut summary)) => {
-            msg!("Error writing files: {}", msg);
-            summary.add_operational_error();
-            summary
-        }
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use super::{format_code_block, format_snippet, Config};
-
-    #[test]
-    fn test_no_panic_on_format_snippet_and_format_code_block() {
-        // `format_snippet()` and `format_code_block()` should not panic
-        // even when we cannot parse the given snippet.
-        let snippet = "let";
-        assert!(format_snippet(snippet, &Config::default()).is_none());
-        assert!(format_code_block(snippet, &Config::default()).is_none());
-    }
-
-    fn test_format_inner<F>(formatter: F, input: &str, expected: &str) -> bool
-    where
-        F: Fn(&str, &Config) -> Option<String>,
-    {
-        let output = formatter(input, &Config::default());
-        output.is_some() && output.unwrap() == expected
-    }
-
-    #[test]
-    fn test_format_snippet() {
-        let snippet = "fn main() { println!(\"hello, world\"); }";
-        let expected = "fn main() {\n    \
-                        println!(\"hello, world\");\n\
-                        }\n";
-        assert!(test_format_inner(format_snippet, snippet, expected));
-    }
-
-    #[test]
-    fn test_format_code_block() {
-        // simple code block
-        let code_block = "let x=3;";
-        let expected = "let x = 3;";
-        assert!(test_format_inner(format_code_block, code_block, expected));
-
-        // more complex code block, taken from chains.rs.
-        let code_block =
-"let (nested_shape, extend) = if !parent_rewrite_contains_newline && is_continuable(&parent) {
-(
-chain_indent(context, shape.add_offset(parent_rewrite.len())),
-context.config.indent_style() == IndentStyle::Visual || is_small_parent,
-)
-} else if is_block_expr(context, &parent, &parent_rewrite) {
-match context.config.indent_style() {
-// Try to put the first child on the same line with parent's last line
-IndentStyle::Block => (parent_shape.block_indent(context.config.tab_spaces()), true),
-// The parent is a block, so align the rest of the chain with the closing
-// brace.
-IndentStyle::Visual => (parent_shape, false),
-}
-} else {
-(
-chain_indent(context, shape.add_offset(parent_rewrite.len())),
-false,
-)
-};
-";
-        let expected =
-"let (nested_shape, extend) = if !parent_rewrite_contains_newline && is_continuable(&parent) {
-    (
-        chain_indent(context, shape.add_offset(parent_rewrite.len())),
-        context.config.indent_style() == IndentStyle::Visual || is_small_parent,
-    )
-} else if is_block_expr(context, &parent, &parent_rewrite) {
-    match context.config.indent_style() {
-        // Try to put the first child on the same line with parent's last line
-        IndentStyle::Block => (parent_shape.block_indent(context.config.tab_spaces()), true),
-        // The parent is a block, so align the rest of the chain with the closing
-        // brace.
-        IndentStyle::Visual => (parent_shape, false),
-    }
-} else {
-    (
-        chain_indent(context, shape.add_offset(parent_rewrite.len())),
-        false,
-    )
-};";
-        assert!(test_format_inner(format_code_block, code_block, expected));
-    }
-}
diff --git a/src/lists.rs b/src/lists.rs
deleted file mode 100644
index aa1e0b430ef..00000000000
--- a/src/lists.rs
+++ /dev/null
@@ -1,857 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::cmp;
-use std::iter::Peekable;
-
-use syntax::codemap::{BytePos, CodeMap};
-
-use comment::{find_comment_end, rewrite_comment, FindUncommented};
-use config::{Config, IndentStyle};
-use rewrite::RewriteContext;
-use shape::{Indent, Shape};
-use utils::{count_newlines, first_line_width, last_line_width, mk_sp, starts_with_newline};
-
-/// Formatting tactic for lists. This will be cast down to a
-/// `DefinitiveListTactic` depending on the number and length of the items and
-/// their comments.
-#[derive(Eq, PartialEq, Debug, Copy, Clone)]
-pub enum ListTactic {
-    // One item per row.
-    Vertical,
-    // All items on one row.
-    Horizontal,
-    // Try Horizontal layout, if that fails then vertical.
-    HorizontalVertical,
-    // HorizontalVertical with a soft limit of n characters.
-    LimitedHorizontalVertical(usize),
-    // Pack as many items as possible per row over (possibly) many rows.
-    Mixed,
-}
-
-impl_enum_serialize_and_deserialize!(ListTactic, Vertical, Horizontal, HorizontalVertical, Mixed);
-
-#[derive(Eq, PartialEq, Debug, Copy, Clone)]
-pub enum SeparatorTactic {
-    Always,
-    Never,
-    Vertical,
-}
-
-impl_enum_serialize_and_deserialize!(SeparatorTactic, Always, Never, Vertical);
-
-impl SeparatorTactic {
-    pub fn from_bool(b: bool) -> SeparatorTactic {
-        if b {
-            SeparatorTactic::Always
-        } else {
-            SeparatorTactic::Never
-        }
-    }
-}
-
-pub struct ListFormatting<'a> {
-    pub tactic: DefinitiveListTactic,
-    pub separator: &'a str,
-    pub trailing_separator: SeparatorTactic,
-    pub separator_place: SeparatorPlace,
-    pub shape: Shape,
-    // Non-expressions, e.g. items, will have a new line at the end of the list.
-    // Important for comment styles.
-    pub ends_with_newline: bool,
-    // Remove newlines between list elements for expressions.
-    pub preserve_newline: bool,
-    pub config: &'a Config,
-}
-
-impl<'a> ListFormatting<'a> {
-    pub fn needs_trailing_separator(&self) -> bool {
-        match self.trailing_separator {
-            // We always put separator in front.
-            SeparatorTactic::Always => true,
-            SeparatorTactic::Vertical => self.tactic == DefinitiveListTactic::Vertical,
-            SeparatorTactic::Never => {
-                self.tactic == DefinitiveListTactic::Vertical && self.separator_place.is_front()
-            }
-        }
-    }
-}
-
-impl AsRef<ListItem> for ListItem {
-    fn as_ref(&self) -> &ListItem {
-        self
-    }
-}
-
-#[derive(PartialEq, Eq)]
-pub enum ListItemCommentStyle {
-    // Try to keep the comment on the same line with the item.
-    SameLine,
-    // Put the comment on the previous or the next line of the item.
-    DifferentLine,
-    // No comment available.
-    None,
-}
-
-pub struct ListItem {
-    // None for comments mean that they are not present.
-    pub pre_comment: Option<String>,
-    pub pre_comment_style: ListItemCommentStyle,
-    // Item should include attributes and doc comments. None indicates a failed
-    // rewrite.
-    pub item: Option<String>,
-    pub post_comment: Option<String>,
-    // Whether there is extra whitespace before this item.
-    pub new_lines: bool,
-}
-
-impl ListItem {
-    pub fn inner_as_ref(&self) -> &str {
-        self.item.as_ref().map_or("", |s| s)
-    }
-
-    pub fn is_different_group(&self) -> bool {
-        self.inner_as_ref().contains('\n') || self.pre_comment.is_some()
-            || self.post_comment
-                .as_ref()
-                .map_or(false, |s| s.contains('\n'))
-    }
-
-    pub fn is_multiline(&self) -> bool {
-        self.inner_as_ref().contains('\n')
-            || self.pre_comment
-                .as_ref()
-                .map_or(false, |s| s.contains('\n'))
-            || self.post_comment
-                .as_ref()
-                .map_or(false, |s| s.contains('\n'))
-    }
-
-    pub fn has_comment(&self) -> bool {
-        self.pre_comment
-            .as_ref()
-            .map_or(false, |comment| comment.trim_left().starts_with("//"))
-            || self.post_comment
-                .as_ref()
-                .map_or(false, |comment| comment.trim_left().starts_with("//"))
-    }
-
-    pub fn from_str<S: Into<String>>(s: S) -> ListItem {
-        ListItem {
-            pre_comment: None,
-            pre_comment_style: ListItemCommentStyle::None,
-            item: Some(s.into()),
-            post_comment: None,
-            new_lines: false,
-        }
-    }
-}
-
-/// The definitive formatting tactic for lists.
-#[derive(Eq, PartialEq, Debug, Copy, Clone)]
-pub enum DefinitiveListTactic {
-    Vertical,
-    Horizontal,
-    Mixed,
-    /// Special case tactic for `format!()`, `write!()` style macros.
-    SpecialMacro(usize),
-}
-
-impl DefinitiveListTactic {
-    pub fn ends_with_newline(&self, indent_style: IndentStyle) -> bool {
-        match indent_style {
-            IndentStyle::Block => *self != DefinitiveListTactic::Horizontal,
-            IndentStyle::Visual => false,
-        }
-    }
-}
-
-/// The type of separator for lists.
-#[derive(Copy, Clone, Eq, PartialEq, Debug)]
-pub enum Separator {
-    Comma,
-    VerticalBar,
-}
-
-impl Separator {
-    pub fn len(&self) -> usize {
-        match *self {
-            // 2 = `, `
-            Separator::Comma => 2,
-            // 3 = ` | `
-            Separator::VerticalBar => 3,
-        }
-    }
-}
-
-/// Where to put separator.
-#[derive(Eq, PartialEq, Debug, Copy, Clone)]
-pub enum SeparatorPlace {
-    Front,
-    Back,
-}
-
-impl_enum_serialize_and_deserialize!(SeparatorPlace, Front, Back);
-
-impl SeparatorPlace {
-    pub fn is_front(&self) -> bool {
-        *self == SeparatorPlace::Front
-    }
-
-    pub fn is_back(&self) -> bool {
-        *self == SeparatorPlace::Back
-    }
-
-    pub fn from_tactic(
-        default: SeparatorPlace,
-        tactic: DefinitiveListTactic,
-        sep: &str,
-    ) -> SeparatorPlace {
-        match tactic {
-            DefinitiveListTactic::Vertical => default,
-            _ => if sep == "," {
-                SeparatorPlace::Back
-            } else {
-                default
-            },
-        }
-    }
-}
-
-pub fn definitive_tactic<I, T>(
-    items: I,
-    tactic: ListTactic,
-    sep: Separator,
-    width: usize,
-) -> DefinitiveListTactic
-where
-    I: IntoIterator<Item = T> + Clone,
-    T: AsRef<ListItem>,
-{
-    let pre_line_comments = items
-        .clone()
-        .into_iter()
-        .any(|item| item.as_ref().has_comment());
-
-    let limit = match tactic {
-        _ if pre_line_comments => return DefinitiveListTactic::Vertical,
-        ListTactic::Mixed => return DefinitiveListTactic::Mixed,
-        ListTactic::Horizontal => return DefinitiveListTactic::Horizontal,
-        ListTactic::Vertical => return DefinitiveListTactic::Vertical,
-        ListTactic::LimitedHorizontalVertical(limit) => ::std::cmp::min(width, limit),
-        ListTactic::HorizontalVertical => width,
-    };
-
-    let (sep_count, total_width) = calculate_width(items.clone());
-    let total_sep_len = sep.len() * sep_count.checked_sub(1).unwrap_or(0);
-    let real_total = total_width + total_sep_len;
-
-    if real_total <= limit && !pre_line_comments
-        && !items.into_iter().any(|item| item.as_ref().is_multiline())
-    {
-        DefinitiveListTactic::Horizontal
-    } else {
-        DefinitiveListTactic::Vertical
-    }
-}
-
-// Format a list of commented items into a string.
-// TODO: add unit tests
-pub fn write_list<I, T>(items: I, formatting: &ListFormatting) -> Option<String>
-where
-    I: IntoIterator<Item = T> + Clone,
-    T: AsRef<ListItem>,
-{
-    let tactic = formatting.tactic;
-    let sep_len = formatting.separator.len();
-
-    // Now that we know how we will layout, we can decide for sure if there
-    // will be a trailing separator.
-    let mut trailing_separator = formatting.needs_trailing_separator();
-    let mut result = String::with_capacity(128);
-    let cloned_items = items.clone();
-    let mut iter = items.into_iter().enumerate().peekable();
-    let mut item_max_width: Option<usize> = None;
-    let sep_place =
-        SeparatorPlace::from_tactic(formatting.separator_place, tactic, formatting.separator);
-
-    let mut line_len = 0;
-    let indent_str = &formatting.shape.indent.to_string(formatting.config);
-    while let Some((i, item)) = iter.next() {
-        let item = item.as_ref();
-        let inner_item = item.item.as_ref()?;
-        let first = i == 0;
-        let last = iter.peek().is_none();
-        let mut separate = match sep_place {
-            SeparatorPlace::Front => !first,
-            SeparatorPlace::Back => !last || trailing_separator,
-        };
-        let item_sep_len = if separate { sep_len } else { 0 };
-
-        // Item string may be multi-line. Its length (used for block comment alignment)
-        // should be only the length of the last line.
-        let item_last_line = if item.is_multiline() {
-            inner_item.lines().last().unwrap_or("")
-        } else {
-            inner_item.as_ref()
-        };
-        let mut item_last_line_width = item_last_line.len() + item_sep_len;
-        if item_last_line.starts_with(&**indent_str) {
-            item_last_line_width -= indent_str.len();
-        }
-
-        match tactic {
-            DefinitiveListTactic::Horizontal if !first => {
-                result.push(' ');
-            }
-            DefinitiveListTactic::SpecialMacro(num_args_before) => {
-                if i == 0 {
-                    // Nothing
-                } else if i < num_args_before {
-                    result.push(' ');
-                } else if i <= num_args_before + 1 {
-                    result.push('\n');
-                    result.push_str(indent_str);
-                } else {
-                    result.push(' ');
-                }
-            }
-            DefinitiveListTactic::Vertical if !first => {
-                result.push('\n');
-                result.push_str(indent_str);
-            }
-            DefinitiveListTactic::Mixed => {
-                let total_width = total_item_width(item) + item_sep_len;
-
-                // 1 is space between separator and item.
-                if line_len > 0 && line_len + 1 + total_width > formatting.shape.width {
-                    result.push('\n');
-                    result.push_str(indent_str);
-                    line_len = 0;
-                    if formatting.ends_with_newline {
-                        if last {
-                            separate = true;
-                        } else {
-                            trailing_separator = true;
-                        }
-                    }
-                }
-
-                if line_len > 0 {
-                    result.push(' ');
-                    line_len += 1;
-                }
-
-                line_len += total_width;
-            }
-            _ => {}
-        }
-
-        // Pre-comments
-        if let Some(ref comment) = item.pre_comment {
-            // Block style in non-vertical mode.
-            let block_mode = tactic != DefinitiveListTactic::Vertical;
-            // Width restriction is only relevant in vertical mode.
-            let comment =
-                rewrite_comment(comment, block_mode, formatting.shape, formatting.config)?;
-            result.push_str(&comment);
-
-            if tactic == DefinitiveListTactic::Vertical {
-                // We cannot keep pre-comments on the same line if the comment if normalized.
-                let keep_comment = if formatting.config.normalize_comments()
-                    || item.pre_comment_style == ListItemCommentStyle::DifferentLine
-                {
-                    false
-                } else {
-                    // We will try to keep the comment on the same line with the item here.
-                    // 1 = ` `
-                    let total_width = total_item_width(item) + item_sep_len + 1;
-                    total_width <= formatting.shape.width
-                };
-                if keep_comment {
-                    result.push(' ');
-                } else {
-                    result.push('\n');
-                    result.push_str(indent_str);
-                }
-            } else {
-                result.push(' ');
-            }
-            item_max_width = None;
-        }
-
-        if separate && sep_place.is_front() && !first {
-            result.push_str(formatting.separator.trim());
-            result.push(' ');
-        }
-        result.push_str(&inner_item[..]);
-
-        // Post-comments
-        if tactic != DefinitiveListTactic::Vertical && item.post_comment.is_some() {
-            let comment = item.post_comment.as_ref().unwrap();
-            let formatted_comment = rewrite_comment(
-                comment,
-                true,
-                Shape::legacy(formatting.shape.width, Indent::empty()),
-                formatting.config,
-            )?;
-
-            result.push(' ');
-            result.push_str(&formatted_comment);
-        }
-
-        if separate && sep_place.is_back() {
-            result.push_str(formatting.separator);
-        }
-
-        if tactic == DefinitiveListTactic::Vertical && item.post_comment.is_some() {
-            let comment = item.post_comment.as_ref().unwrap();
-            let overhead = last_line_width(&result) + first_line_width(comment.trim());
-
-            let rewrite_post_comment = |item_max_width: &mut Option<usize>| {
-                if item_max_width.is_none() && !last && !inner_item.contains('\n') {
-                    *item_max_width = Some(max_width_of_item_with_post_comment(
-                        &cloned_items,
-                        i,
-                        overhead,
-                        formatting.config.max_width(),
-                    ));
-                }
-                let overhead = if starts_with_newline(comment) {
-                    0
-                } else if let Some(max_width) = *item_max_width {
-                    max_width + 2
-                } else {
-                    // 1 = space between item and comment.
-                    item_last_line_width + 1
-                };
-                let width = formatting.shape.width.checked_sub(overhead).unwrap_or(1);
-                let offset = formatting.shape.indent + overhead;
-                let comment_shape = Shape::legacy(width, offset);
-
-                // Use block-style only for the last item or multiline comments.
-                let block_style = !formatting.ends_with_newline && last
-                    || comment.trim().contains('\n')
-                    || comment.trim().len() > width;
-
-                rewrite_comment(
-                    comment.trim_left(),
-                    block_style,
-                    comment_shape,
-                    formatting.config,
-                )
-            };
-
-            let mut formatted_comment = rewrite_post_comment(&mut item_max_width)?;
-
-            if !starts_with_newline(comment) {
-                let mut comment_alignment =
-                    post_comment_alignment(item_max_width, inner_item.len());
-                if first_line_width(&formatted_comment) + last_line_width(&result)
-                    + comment_alignment + 1 > formatting.config.max_width()
-                {
-                    item_max_width = None;
-                    formatted_comment = rewrite_post_comment(&mut item_max_width)?;
-                    comment_alignment = post_comment_alignment(item_max_width, inner_item.len());
-                }
-                for _ in 0..(comment_alignment + 1) {
-                    result.push(' ');
-                }
-                // An additional space for the missing trailing separator.
-                if last && item_max_width.is_some() && !separate && !formatting.separator.is_empty()
-                {
-                    result.push(' ');
-                }
-            } else {
-                result.push('\n');
-                result.push_str(indent_str);
-            }
-            if formatted_comment.contains('\n') {
-                item_max_width = None;
-            }
-            result.push_str(&formatted_comment);
-        } else {
-            item_max_width = None;
-        }
-
-        if formatting.preserve_newline && !last && tactic == DefinitiveListTactic::Vertical
-            && item.new_lines
-        {
-            item_max_width = None;
-            result.push('\n');
-        }
-    }
-
-    Some(result)
-}
-
-fn max_width_of_item_with_post_comment<I, T>(
-    items: &I,
-    i: usize,
-    overhead: usize,
-    max_budget: usize,
-) -> usize
-where
-    I: IntoIterator<Item = T> + Clone,
-    T: AsRef<ListItem>,
-{
-    let mut max_width = 0;
-    let mut first = true;
-    for item in items.clone().into_iter().skip(i) {
-        let item = item.as_ref();
-        let inner_item_width = item.inner_as_ref().len();
-        if !first
-            && (item.is_different_group() || !item.post_comment.is_some()
-                || inner_item_width + overhead > max_budget)
-        {
-            return max_width;
-        }
-        if max_width < inner_item_width {
-            max_width = inner_item_width;
-        }
-        if item.new_lines {
-            return max_width;
-        }
-        first = false;
-    }
-    max_width
-}
-
-fn post_comment_alignment(item_max_width: Option<usize>, inner_item_len: usize) -> usize {
-    item_max_width
-        .and_then(|max_line_width| max_line_width.checked_sub(inner_item_len))
-        .unwrap_or(0)
-}
-
-pub struct ListItems<'a, I, F1, F2, F3>
-where
-    I: Iterator,
-{
-    codemap: &'a CodeMap,
-    inner: Peekable<I>,
-    get_lo: F1,
-    get_hi: F2,
-    get_item_string: F3,
-    prev_span_end: BytePos,
-    next_span_start: BytePos,
-    terminator: &'a str,
-    separator: &'a str,
-    leave_last: bool,
-}
-
-impl<'a, T, I, F1, F2, F3> Iterator for ListItems<'a, I, F1, F2, F3>
-where
-    I: Iterator<Item = T>,
-    F1: Fn(&T) -> BytePos,
-    F2: Fn(&T) -> BytePos,
-    F3: Fn(&T) -> Option<String>,
-{
-    type Item = ListItem;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        let white_space: &[_] = &[' ', '\t'];
-
-        self.inner.next().map(|item| {
-            let mut new_lines = false;
-            // Pre-comment
-            let pre_snippet = self.codemap
-                .span_to_snippet(mk_sp(self.prev_span_end, (self.get_lo)(&item)))
-                .unwrap();
-            let trimmed_pre_snippet = pre_snippet.trim();
-            let has_single_line_comment = trimmed_pre_snippet.starts_with("//");
-            let has_block_comment = trimmed_pre_snippet.starts_with("/*");
-            let (pre_comment, pre_comment_style) = if has_single_line_comment {
-                (
-                    Some(trimmed_pre_snippet.to_owned()),
-                    ListItemCommentStyle::DifferentLine,
-                )
-            } else if has_block_comment {
-                let comment_end = pre_snippet.chars().rev().position(|c| c == '/').unwrap();
-                if pre_snippet
-                    .chars()
-                    .rev()
-                    .take(comment_end + 1)
-                    .any(|c| c == '\n')
-                {
-                    (
-                        Some(trimmed_pre_snippet.to_owned()),
-                        ListItemCommentStyle::DifferentLine,
-                    )
-                } else {
-                    (
-                        Some(trimmed_pre_snippet.to_owned()),
-                        ListItemCommentStyle::SameLine,
-                    )
-                }
-            } else {
-                (None, ListItemCommentStyle::None)
-            };
-
-            // Post-comment
-            let next_start = match self.inner.peek() {
-                Some(next_item) => (self.get_lo)(next_item),
-                None => self.next_span_start,
-            };
-            let post_snippet = self.codemap
-                .span_to_snippet(mk_sp((self.get_hi)(&item), next_start))
-                .unwrap();
-
-            let comment_end = match self.inner.peek() {
-                Some(..) => {
-                    let mut block_open_index = post_snippet.find("/*");
-                    // check if it really is a block comment (and not `//*` or a nested comment)
-                    if let Some(i) = block_open_index {
-                        match post_snippet.find('/') {
-                            Some(j) if j < i => block_open_index = None,
-                            _ if i > 0 && &post_snippet[i - 1..i] == "/" => block_open_index = None,
-                            _ => (),
-                        }
-                    }
-                    let newline_index = post_snippet.find('\n');
-                    if let Some(separator_index) = post_snippet.find_uncommented(self.separator) {
-                        match (block_open_index, newline_index) {
-                            // Separator before comment, with the next item on same line.
-                            // Comment belongs to next item.
-                            (Some(i), None) if i > separator_index => separator_index + 1,
-                            // Block-style post-comment before the separator.
-                            (Some(i), None) => cmp::max(
-                                find_comment_end(&post_snippet[i..]).unwrap() + i,
-                                separator_index + 1,
-                            ),
-                            // Block-style post-comment. Either before or after the separator.
-                            (Some(i), Some(j)) if i < j => cmp::max(
-                                find_comment_end(&post_snippet[i..]).unwrap() + i,
-                                separator_index + 1,
-                            ),
-                            // Potential *single* line comment.
-                            (_, Some(j)) if j > separator_index => j + 1,
-                            _ => post_snippet.len(),
-                        }
-                    } else if let Some(newline_index) = newline_index {
-                        // Match arms may not have trailing comma. In any case, for match arms,
-                        // we will assume that the post comment belongs to the next arm if they
-                        // do not end with trailing comma.
-                        newline_index + 1
-                    } else {
-                        0
-                    }
-                }
-                None => post_snippet
-                    .find_uncommented(self.terminator)
-                    .unwrap_or_else(|| post_snippet.len()),
-            };
-
-            if !post_snippet.is_empty() && comment_end > 0 {
-                // Account for extra whitespace between items. This is fiddly
-                // because of the way we divide pre- and post- comments.
-
-                // Everything from the separator to the next item.
-                let test_snippet = &post_snippet[comment_end - 1..];
-                let first_newline = test_snippet
-                    .find('\n')
-                    .unwrap_or_else(|| test_snippet.len());
-                // From the end of the first line of comments.
-                let test_snippet = &test_snippet[first_newline..];
-                let first = test_snippet
-                    .find(|c: char| !c.is_whitespace())
-                    .unwrap_or_else(|| test_snippet.len());
-                // From the end of the first line of comments to the next non-whitespace char.
-                let test_snippet = &test_snippet[..first];
-
-                if count_newlines(test_snippet) > 1 {
-                    // There were multiple line breaks which got trimmed to nothing.
-                    new_lines = true;
-                }
-            }
-
-            // Cleanup post-comment: strip separators and whitespace.
-            self.prev_span_end = (self.get_hi)(&item) + BytePos(comment_end as u32);
-            let post_snippet = post_snippet[..comment_end].trim();
-
-            let post_snippet_trimmed = if post_snippet.starts_with(|c| c == ',' || c == ':') {
-                post_snippet[1..].trim_matches(white_space)
-            } else if post_snippet.ends_with(',') {
-                post_snippet[..(post_snippet.len() - 1)].trim_matches(white_space)
-            } else {
-                post_snippet
-            };
-
-            let post_comment = if !post_snippet_trimmed.is_empty() {
-                Some(post_snippet_trimmed.to_owned())
-            } else {
-                None
-            };
-
-            ListItem {
-                pre_comment,
-                pre_comment_style,
-                item: if self.inner.peek().is_none() && self.leave_last {
-                    None
-                } else {
-                    (self.get_item_string)(&item)
-                },
-                post_comment,
-                new_lines,
-            }
-        })
-    }
-}
-
-// Creates an iterator over a list's items with associated comments.
-pub fn itemize_list<'a, T, I, F1, F2, F3>(
-    codemap: &'a CodeMap,
-    inner: I,
-    terminator: &'a str,
-    separator: &'a str,
-    get_lo: F1,
-    get_hi: F2,
-    get_item_string: F3,
-    prev_span_end: BytePos,
-    next_span_start: BytePos,
-    leave_last: bool,
-) -> ListItems<'a, I, F1, F2, F3>
-where
-    I: Iterator<Item = T>,
-    F1: Fn(&T) -> BytePos,
-    F2: Fn(&T) -> BytePos,
-    F3: Fn(&T) -> Option<String>,
-{
-    ListItems {
-        codemap,
-        inner: inner.peekable(),
-        get_lo,
-        get_hi,
-        get_item_string,
-        prev_span_end,
-        next_span_start,
-        terminator,
-        separator,
-        leave_last,
-    }
-}
-
-/// Returns the count and total width of the list items.
-fn calculate_width<I, T>(items: I) -> (usize, usize)
-where
-    I: IntoIterator<Item = T>,
-    T: AsRef<ListItem>,
-{
-    items
-        .into_iter()
-        .map(|item| total_item_width(item.as_ref()))
-        .fold((0, 0), |acc, l| (acc.0 + 1, acc.1 + l))
-}
-
-pub fn total_item_width(item: &ListItem) -> usize {
-    comment_len(item.pre_comment.as_ref().map(|x| &(*x)[..]))
-        + comment_len(item.post_comment.as_ref().map(|x| &(*x)[..]))
-        + item.item.as_ref().map_or(0, |str| str.len())
-}
-
-fn comment_len(comment: Option<&str>) -> usize {
-    match comment {
-        Some(s) => {
-            let text_len = s.trim().len();
-            if text_len > 0 {
-                // We'll put " /*" before and " */" after inline comments.
-                text_len + 6
-            } else {
-                text_len
-            }
-        }
-        None => 0,
-    }
-}
-
-// Compute horizontal and vertical shapes for a struct-lit-like thing.
-pub fn struct_lit_shape(
-    shape: Shape,
-    context: &RewriteContext,
-    prefix_width: usize,
-    suffix_width: usize,
-) -> Option<(Option<Shape>, Shape)> {
-    let v_shape = match context.config.indent_style() {
-        IndentStyle::Visual => shape
-            .visual_indent(0)
-            .shrink_left(prefix_width)?
-            .sub_width(suffix_width)?,
-        IndentStyle::Block => {
-            let shape = shape.block_indent(context.config.tab_spaces());
-            Shape {
-                width: context.budget(shape.indent.width()),
-                ..shape
-            }
-        }
-    };
-    let shape_width = shape.width.checked_sub(prefix_width + suffix_width);
-    if let Some(w) = shape_width {
-        let shape_width = cmp::min(w, context.config.width_heuristics().struct_lit_width);
-        Some((Some(Shape::legacy(shape_width, shape.indent)), v_shape))
-    } else {
-        Some((None, v_shape))
-    }
-}
-
-// Compute the tactic for the internals of a struct-lit-like thing.
-pub fn struct_lit_tactic(
-    h_shape: Option<Shape>,
-    context: &RewriteContext,
-    items: &[ListItem],
-) -> DefinitiveListTactic {
-    if let Some(h_shape) = h_shape {
-        let prelim_tactic = match (context.config.indent_style(), items.len()) {
-            (IndentStyle::Visual, 1) => ListTactic::HorizontalVertical,
-            _ if context.config.struct_lit_single_line() => ListTactic::HorizontalVertical,
-            _ => ListTactic::Vertical,
-        };
-        definitive_tactic(items, prelim_tactic, Separator::Comma, h_shape.width)
-    } else {
-        DefinitiveListTactic::Vertical
-    }
-}
-
-// Given a tactic and possible shapes for horizontal and vertical layout,
-// come up with the actual shape to use.
-pub fn shape_for_tactic(
-    tactic: DefinitiveListTactic,
-    h_shape: Option<Shape>,
-    v_shape: Shape,
-) -> Shape {
-    match tactic {
-        DefinitiveListTactic::Horizontal => h_shape.unwrap(),
-        _ => v_shape,
-    }
-}
-
-// Create a ListFormatting object for formatting the internals of a
-// struct-lit-like thing, that is a series of fields.
-pub fn struct_lit_formatting<'a>(
-    shape: Shape,
-    tactic: DefinitiveListTactic,
-    context: &'a RewriteContext,
-    force_no_trailing_comma: bool,
-) -> ListFormatting<'a> {
-    let ends_with_newline = context.config.indent_style() != IndentStyle::Visual
-        && tactic == DefinitiveListTactic::Vertical;
-    ListFormatting {
-        tactic,
-        separator: ",",
-        trailing_separator: if force_no_trailing_comma {
-            SeparatorTactic::Never
-        } else {
-            context.config.trailing_comma()
-        },
-        separator_place: SeparatorPlace::Back,
-        shape,
-        ends_with_newline,
-        preserve_newline: true,
-        config: context.config,
-    }
-}
diff --git a/src/macros.rs b/src/macros.rs
deleted file mode 100644
index 3abfe6239fd..00000000000
--- a/src/macros.rs
+++ /dev/null
@@ -1,871 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Format list-like macro invocations. These are invocations whose token trees
-// can be interpreted as expressions and separated by commas.
-// Note that these token trees do not actually have to be interpreted as
-// expressions by the compiler. An example of an invocation we would reformat is
-// foo!( x, y, z ). The token x may represent an identifier in the code, but we
-// interpreted as an expression.
-// Macro uses which are not-list like, such as bar!(key => val), will not be
-// reformatted.
-// List-like invocations with parentheses will be formatted as function calls,
-// and those with brackets will be formatted as array literals.
-
-use std::collections::HashMap;
-use syntax::ast;
-use syntax::codemap::{BytePos, Span};
-use syntax::parse::new_parser_from_tts;
-use syntax::parse::parser::Parser;
-use syntax::parse::token::{BinOpToken, DelimToken, Token};
-use syntax::print::pprust;
-use syntax::symbol;
-use syntax::tokenstream::{Cursor, ThinTokenStream, TokenStream, TokenTree};
-use syntax::util::ThinVec;
-
-use codemap::SpanUtils;
-use comment::{contains_comment, remove_trailing_white_spaces, FindUncommented};
-use expr::{rewrite_array, rewrite_call_inner};
-use lists::{itemize_list, write_list, DefinitiveListTactic, ListFormatting, SeparatorPlace,
-            SeparatorTactic};
-use rewrite::{Rewrite, RewriteContext};
-use shape::{Indent, Shape};
-use utils::{format_visibility, mk_sp};
-
-const FORCED_BRACKET_MACROS: &[&str] = &["vec!"];
-
-// FIXME: use the enum from libsyntax?
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-enum MacroStyle {
-    Parens,
-    Brackets,
-    Braces,
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub enum MacroPosition {
-    Item,
-    Statement,
-    Expression,
-    Pat,
-}
-
-impl MacroStyle {
-    fn opener(&self) -> &'static str {
-        match *self {
-            MacroStyle::Parens => "(",
-            MacroStyle::Brackets => "[",
-            MacroStyle::Braces => "{",
-        }
-    }
-}
-
-#[derive(Debug)]
-pub enum MacroArg {
-    Expr(ast::Expr),
-    Ty(ast::Ty),
-    Pat(ast::Pat),
-}
-
-impl Rewrite for MacroArg {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        match *self {
-            MacroArg::Expr(ref expr) => expr.rewrite(context, shape),
-            MacroArg::Ty(ref ty) => ty.rewrite(context, shape),
-            MacroArg::Pat(ref pat) => pat.rewrite(context, shape),
-        }
-    }
-}
-
-fn parse_macro_arg(parser: &mut Parser) -> Option<MacroArg> {
-    macro_rules! parse_macro_arg {
-        ($macro_arg: ident, $parser: ident) => {
-            let mut cloned_parser = (*parser).clone();
-            match cloned_parser.$parser() {
-                Ok(x) => {
-                    if parser.sess.span_diagnostic.has_errors() {
-                        parser.sess.span_diagnostic.reset_err_count();
-                    } else {
-                        // Parsing succeeded.
-                        *parser = cloned_parser;
-                        return Some(MacroArg::$macro_arg((*x).clone()));
-                    }
-                }
-                Err(mut e) => {
-                    e.cancel();
-                    parser.sess.span_diagnostic.reset_err_count();
-                }
-            }
-        };
-    }
-
-    parse_macro_arg!(Expr, parse_expr);
-    parse_macro_arg!(Ty, parse_ty);
-    parse_macro_arg!(Pat, parse_pat);
-
-    None
-}
-
-pub fn rewrite_macro(
-    mac: &ast::Mac,
-    extra_ident: Option<ast::Ident>,
-    context: &RewriteContext,
-    shape: Shape,
-    position: MacroPosition,
-) -> Option<String> {
-    let context = &mut context.clone();
-    context.inside_macro = true;
-    if context.config.use_try_shorthand() {
-        if let Some(expr) = convert_try_mac(mac, context) {
-            context.inside_macro = false;
-            return expr.rewrite(context, shape);
-        }
-    }
-
-    let original_style = macro_style(mac, context);
-
-    let macro_name = match extra_ident {
-        None => format!("{}!", mac.node.path),
-        Some(ident) => {
-            if ident == symbol::keywords::Invalid.ident() {
-                format!("{}!", mac.node.path)
-            } else {
-                format!("{}! {}", mac.node.path, ident)
-            }
-        }
-    };
-
-    let style = if FORCED_BRACKET_MACROS.contains(&&macro_name[..]) {
-        MacroStyle::Brackets
-    } else {
-        original_style
-    };
-
-    let ts: TokenStream = mac.node.stream();
-    if ts.is_empty() && !contains_comment(context.snippet(mac.span)) {
-        return match style {
-            MacroStyle::Parens if position == MacroPosition::Item => {
-                Some(format!("{}();", macro_name))
-            }
-            MacroStyle::Parens => Some(format!("{}()", macro_name)),
-            MacroStyle::Brackets => Some(format!("{}[]", macro_name)),
-            MacroStyle::Braces => Some(format!("{}{{}}", macro_name)),
-        };
-    }
-
-    let mut parser = new_parser_from_tts(context.parse_session, ts.trees().collect());
-    let mut arg_vec = Vec::new();
-    let mut vec_with_semi = false;
-    let mut trailing_comma = false;
-
-    if MacroStyle::Braces != style {
-        loop {
-            match parse_macro_arg(&mut parser) {
-                Some(arg) => arg_vec.push(arg),
-                None => return Some(context.snippet(mac.span).to_owned()),
-            }
-
-            match parser.token {
-                Token::Eof => break,
-                Token::Comma => (),
-                Token::Semi => {
-                    // Try to parse `vec![expr; expr]`
-                    if FORCED_BRACKET_MACROS.contains(&&macro_name[..]) {
-                        parser.bump();
-                        if parser.token != Token::Eof {
-                            match parse_macro_arg(&mut parser) {
-                                Some(arg) => {
-                                    arg_vec.push(arg);
-                                    parser.bump();
-                                    if parser.token == Token::Eof && arg_vec.len() == 2 {
-                                        vec_with_semi = true;
-                                        break;
-                                    }
-                                }
-                                None => return Some(context.snippet(mac.span).to_owned()),
-                            }
-                        }
-                    }
-                    return Some(context.snippet(mac.span).to_owned());
-                }
-                _ => return Some(context.snippet(mac.span).to_owned()),
-            }
-
-            parser.bump();
-
-            if parser.token == Token::Eof {
-                trailing_comma = true;
-                break;
-            }
-        }
-    }
-
-    match style {
-        MacroStyle::Parens => {
-            // Format macro invocation as function call, forcing no trailing
-            // comma because not all macros support them.
-            rewrite_call_inner(
-                context,
-                &macro_name,
-                &arg_vec.iter().map(|e| &*e).collect::<Vec<_>>()[..],
-                mac.span,
-                shape,
-                context.config.width_heuristics().fn_call_width,
-                trailing_comma,
-            ).map(|rw| match position {
-                MacroPosition::Item => format!("{};", rw),
-                _ => rw,
-            })
-        }
-        MacroStyle::Brackets => {
-            let mac_shape = shape.offset_left(macro_name.len())?;
-            // Handle special case: `vec![expr; expr]`
-            if vec_with_semi {
-                let (lbr, rbr) = if context.config.spaces_within_parens_and_brackets() {
-                    ("[ ", " ]")
-                } else {
-                    ("[", "]")
-                };
-                // 6 = `vec!` + `; `
-                let total_overhead = lbr.len() + rbr.len() + 6;
-                let nested_shape = mac_shape.block_indent(context.config.tab_spaces());
-                let lhs = arg_vec[0].rewrite(context, nested_shape)?;
-                let rhs = arg_vec[1].rewrite(context, nested_shape)?;
-                if !lhs.contains('\n') && !rhs.contains('\n')
-                    && lhs.len() + rhs.len() + total_overhead <= shape.width
-                {
-                    Some(format!("{}{}{}; {}{}", macro_name, lbr, lhs, rhs, rbr))
-                } else {
-                    Some(format!(
-                        "{}{}\n{}{};\n{}{}\n{}{}",
-                        macro_name,
-                        lbr,
-                        nested_shape.indent.to_string(context.config),
-                        lhs,
-                        nested_shape.indent.to_string(context.config),
-                        rhs,
-                        shape.indent.to_string(context.config),
-                        rbr
-                    ))
-                }
-            } else {
-                // If we are rewriting `vec!` macro or other special macros,
-                // then we can rewrite this as an usual array literal.
-                // Otherwise, we must preserve the original existence of trailing comma.
-                if FORCED_BRACKET_MACROS.contains(&macro_name.as_str()) {
-                    context.inside_macro = false;
-                    trailing_comma = false;
-                }
-                // Convert `MacroArg` into `ast::Expr`, as `rewrite_array` only accepts the latter.
-                let sp = mk_sp(
-                    context
-                        .codemap
-                        .span_after(mac.span, original_style.opener()),
-                    mac.span.hi() - BytePos(1),
-                );
-                let arg_vec = &arg_vec.iter().map(|e| &*e).collect::<Vec<_>>()[..];
-                let rewrite = rewrite_array(arg_vec, sp, context, mac_shape, trailing_comma)?;
-
-                Some(format!("{}{}", macro_name, rewrite))
-            }
-        }
-        MacroStyle::Braces => {
-            // Skip macro invocations with braces, for now.
-            indent_macro_snippet(context, context.snippet(mac.span), shape.indent)
-        }
-    }
-}
-
-pub fn rewrite_macro_def(
-    context: &RewriteContext,
-    shape: Shape,
-    indent: Indent,
-    def: &ast::MacroDef,
-    ident: ast::Ident,
-    vis: &ast::Visibility,
-    span: Span,
-) -> Option<String> {
-    let snippet = Some(remove_trailing_white_spaces(context.snippet(span)));
-
-    let mut parser = MacroParser::new(def.stream().into_trees());
-    let parsed_def = match parser.parse() {
-        Some(def) => def,
-        None => return snippet,
-    };
-
-    let mut result = if def.legacy {
-        String::from("macro_rules!")
-    } else {
-        format!("{}macro", format_visibility(vis))
-    };
-
-    result += " ";
-    result += &ident.name.as_str();
-
-    let multi_branch_style = def.legacy || parsed_def.branches.len() != 1;
-
-    let arm_shape = if multi_branch_style {
-        shape
-            .block_indent(context.config.tab_spaces())
-            .with_max_width(context.config)
-    } else {
-        shape
-    };
-
-    let branch_items = itemize_list(
-        context.codemap,
-        parsed_def.branches.iter(),
-        "}",
-        ";",
-        |branch| branch.span.lo(),
-        |branch| branch.span.hi(),
-        |branch| branch.rewrite(context, arm_shape, multi_branch_style),
-        context.codemap.span_after(span, "{"),
-        span.hi(),
-        false,
-    ).collect::<Vec<_>>();
-
-    let fmt = ListFormatting {
-        tactic: DefinitiveListTactic::Vertical,
-        separator: if def.legacy { ";" } else { "" },
-        trailing_separator: SeparatorTactic::Always,
-        separator_place: SeparatorPlace::Back,
-        shape: arm_shape,
-        ends_with_newline: true,
-        preserve_newline: true,
-        config: context.config,
-    };
-
-    if multi_branch_style {
-        result += " {\n";
-        result += &arm_shape.indent.to_string(context.config);
-    }
-
-    result += write_list(&branch_items, &fmt)?.as_str();
-
-    if multi_branch_style {
-        result += "\n";
-        result += &indent.to_string(context.config);
-        result += "}";
-    }
-
-    Some(result)
-}
-
-// Replaces `$foo` with `zfoo`. We must check for name overlap to ensure we
-// aren't causing problems.
-// This should also work for escaped `$` variables, where we leave earlier `$`s.
-fn replace_names(input: &str) -> Option<(String, HashMap<String, String>)> {
-    // Each substitution will require five or six extra bytes.
-    let mut result = String::with_capacity(input.len() + 64);
-    let mut substs = HashMap::new();
-    let mut dollar_count = 0;
-    let mut cur_name = String::new();
-
-    for c in input.chars() {
-        if c == '$' {
-            dollar_count += 1;
-        } else if dollar_count == 0 {
-            result.push(c);
-        } else if !c.is_alphanumeric() && !cur_name.is_empty() {
-            // Terminates a name following one or more dollars.
-            let mut new_name = String::new();
-            let mut old_name = String::new();
-            old_name.push('$');
-            for _ in 0..(dollar_count - 1) {
-                new_name.push('$');
-                old_name.push('$');
-            }
-            new_name.push('z');
-            new_name.push_str(&cur_name);
-            old_name.push_str(&cur_name);
-
-            result.push_str(&new_name);
-            substs.insert(old_name, new_name);
-
-            result.push(c);
-
-            dollar_count = 0;
-            cur_name = String::new();
-        } else if c == '(' && cur_name.is_empty() {
-            // FIXME: Support macro def with repeat.
-            return None;
-        } else if c.is_alphanumeric() {
-            cur_name.push(c);
-        }
-    }
-
-    // FIXME: duplicate code
-    if !cur_name.is_empty() {
-        let mut new_name = String::new();
-        let mut old_name = String::new();
-        old_name.push('$');
-        for _ in 0..(dollar_count - 1) {
-            new_name.push('$');
-            old_name.push('$');
-        }
-        new_name.push('z');
-        new_name.push_str(&cur_name);
-        old_name.push_str(&cur_name);
-
-        result.push_str(&new_name);
-        substs.insert(old_name, new_name);
-    }
-
-    debug!("replace_names `{}` {:?}", result, substs);
-
-    Some((result, substs))
-}
-
-// This is a bit sketchy. The token rules probably need tweaking, but it works
-// for some common cases. I hope the basic logic is sufficient. Note that the
-// meaning of some tokens is a bit different here from usual Rust, e.g., `*`
-// and `(`/`)` have special meaning.
-//
-// We always try and format on one line.
-fn format_macro_args(toks: ThinTokenStream) -> Option<String> {
-    let mut result = String::with_capacity(128);
-    let mut insert_space = SpaceState::Never;
-
-    for tok in (toks.into(): TokenStream).trees() {
-        match tok {
-            TokenTree::Token(_, t) => {
-                if !result.is_empty() && force_space_before(&t) {
-                    insert_space = SpaceState::Always;
-                }
-                if force_no_space_before(&t) {
-                    insert_space = SpaceState::Never;
-                }
-                match (insert_space, ident_like(&t)) {
-                    (SpaceState::Always, _)
-                    | (SpaceState::Punctuation, false)
-                    | (SpaceState::Ident, true) => {
-                        result.push(' ');
-                    }
-                    _ => {}
-                }
-                result.push_str(&pprust::token_to_string(&t));
-                insert_space = next_space(&t);
-            }
-            TokenTree::Delimited(_, d) => {
-                if let SpaceState::Always = insert_space {
-                    result.push(' ');
-                }
-                let formatted = format_macro_args(d.tts)?;
-                match d.delim {
-                    DelimToken::Paren => {
-                        result.push_str(&format!("({})", formatted));
-                        insert_space = SpaceState::Always;
-                    }
-                    DelimToken::Bracket => {
-                        result.push_str(&format!("[{}]", formatted));
-                        insert_space = SpaceState::Always;
-                    }
-                    DelimToken::Brace => {
-                        result.push_str(&format!(" {{ {} }}", formatted));
-                        insert_space = SpaceState::Always;
-                    }
-                    DelimToken::NoDelim => {
-                        result.push_str(&format!("{}", formatted));
-                        insert_space = SpaceState::Always;
-                    }
-                }
-            }
-        }
-    }
-
-    Some(result)
-}
-
-// We should insert a space if the next token is a:
-#[derive(Copy, Clone)]
-enum SpaceState {
-    Never,
-    Punctuation,
-    Ident, // Or ident/literal-like thing.
-    Always,
-}
-
-fn force_space_before(tok: &Token) -> bool {
-    match *tok {
-        Token::Eq
-        | Token::Lt
-        | Token::Le
-        | Token::EqEq
-        | Token::Ne
-        | Token::Ge
-        | Token::Gt
-        | Token::AndAnd
-        | Token::OrOr
-        | Token::Not
-        | Token::Tilde
-        | Token::BinOpEq(_)
-        | Token::At
-        | Token::RArrow
-        | Token::LArrow
-        | Token::FatArrow
-        | Token::Pound
-        | Token::Dollar => true,
-        Token::BinOp(bot) => bot != BinOpToken::Star,
-        _ => false,
-    }
-}
-
-fn force_no_space_before(tok: &Token) -> bool {
-    match *tok {
-        Token::Semi | Token::Comma | Token::Dot => true,
-        Token::BinOp(bot) => bot == BinOpToken::Star,
-        _ => false,
-    }
-}
-fn ident_like(tok: &Token) -> bool {
-    match *tok {
-        Token::Ident(_) | Token::Literal(..) | Token::Lifetime(_) => true,
-        _ => false,
-    }
-}
-
-fn next_space(tok: &Token) -> SpaceState {
-    match *tok {
-        Token::Not
-        | Token::Tilde
-        | Token::At
-        | Token::Comma
-        | Token::Dot
-        | Token::DotDot
-        | Token::DotDotDot
-        | Token::DotDotEq
-        | Token::DotEq
-        | Token::Question
-        | Token::Underscore
-        | Token::BinOp(_) => SpaceState::Punctuation,
-
-        Token::ModSep
-        | Token::Pound
-        | Token::Dollar
-        | Token::OpenDelim(_)
-        | Token::CloseDelim(_)
-        | Token::Whitespace => SpaceState::Never,
-
-        Token::Literal(..) | Token::Ident(_) | Token::Lifetime(_) => SpaceState::Ident,
-
-        _ => SpaceState::Always,
-    }
-}
-
-/// Tries to convert a macro use into a short hand try expression. Returns None
-/// when the macro is not an instance of try! (or parsing the inner expression
-/// failed).
-pub fn convert_try_mac(mac: &ast::Mac, context: &RewriteContext) -> Option<ast::Expr> {
-    if &format!("{}", mac.node.path)[..] == "try" {
-        let ts: TokenStream = mac.node.tts.clone().into();
-        let mut parser = new_parser_from_tts(context.parse_session, ts.trees().collect());
-
-        Some(ast::Expr {
-            id: ast::NodeId::new(0), // dummy value
-            node: ast::ExprKind::Try(parser.parse_expr().ok()?),
-            span: mac.span, // incorrect span, but shouldn't matter too much
-            attrs: ThinVec::new(),
-        })
-    } else {
-        None
-    }
-}
-
-fn macro_style(mac: &ast::Mac, context: &RewriteContext) -> MacroStyle {
-    let snippet = context.snippet(mac.span);
-    let paren_pos = snippet.find_uncommented("(").unwrap_or(usize::max_value());
-    let bracket_pos = snippet.find_uncommented("[").unwrap_or(usize::max_value());
-    let brace_pos = snippet.find_uncommented("{").unwrap_or(usize::max_value());
-
-    if paren_pos < bracket_pos && paren_pos < brace_pos {
-        MacroStyle::Parens
-    } else if bracket_pos < brace_pos {
-        MacroStyle::Brackets
-    } else {
-        MacroStyle::Braces
-    }
-}
-
-/// Indent each line according to the specified `indent`.
-/// e.g.
-/// ```rust
-/// foo!{
-/// x,
-/// y,
-/// foo(
-///     a,
-///     b,
-///     c,
-/// ),
-/// }
-/// ```
-/// will become
-/// ```rust
-/// foo!{
-///     x,
-///     y,
-///     foo(
-///         a,
-///         b,
-///         c,
-//      ),
-/// }
-/// ```
-fn indent_macro_snippet(
-    context: &RewriteContext,
-    macro_str: &str,
-    indent: Indent,
-) -> Option<String> {
-    let mut lines = macro_str.lines();
-    let first_line = lines.next().map(|s| s.trim_right())?;
-    let mut trimmed_lines = Vec::with_capacity(16);
-
-    let min_prefix_space_width = lines
-        .filter_map(|line| {
-            let prefix_space_width = if is_empty_line(line) {
-                None
-            } else {
-                Some(get_prefix_space_width(context, line))
-            };
-            trimmed_lines.push((line.trim(), prefix_space_width));
-            prefix_space_width
-        })
-        .min()?;
-
-    Some(
-        String::from(first_line) + "\n"
-            + &trimmed_lines
-                .iter()
-                .map(|&(line, prefix_space_width)| match prefix_space_width {
-                    Some(original_indent_width) => {
-                        let new_indent_width = indent.width()
-                            + original_indent_width
-                                .checked_sub(min_prefix_space_width)
-                                .unwrap_or(0);
-                        let new_indent = Indent::from_width(context.config, new_indent_width);
-                        format!("{}{}", new_indent.to_string(context.config), line.trim())
-                    }
-                    None => String::new(),
-                })
-                .collect::<Vec<_>>()
-                .join("\n"),
-    )
-}
-
-fn get_prefix_space_width(context: &RewriteContext, s: &str) -> usize {
-    let mut width = 0;
-    for c in s.chars() {
-        match c {
-            ' ' => width += 1,
-            '\t' => width += context.config.tab_spaces(),
-            _ => return width,
-        }
-    }
-    width
-}
-
-fn is_empty_line(s: &str) -> bool {
-    s.is_empty() || s.chars().all(char::is_whitespace)
-}
-
-// A very simple parser that just parses a macros 2.0 definition into its branches.
-// Currently we do not attempt to parse any further than that.
-#[derive(new)]
-struct MacroParser {
-    toks: Cursor,
-}
-
-impl MacroParser {
-    // (`(` ... `)` `=>` `{` ... `}`)*
-    fn parse(&mut self) -> Option<Macro> {
-        let mut branches = vec![];
-        while self.toks.look_ahead(1).is_some() {
-            branches.push(self.parse_branch()?);
-        }
-
-        Some(Macro { branches })
-    }
-
-    // `(` ... `)` `=>` `{` ... `}`
-    fn parse_branch(&mut self) -> Option<MacroBranch> {
-        let tok = self.toks.next()?;
-        let (lo, args_paren_kind) = match tok {
-            TokenTree::Token(..) => return None,
-            TokenTree::Delimited(sp, ref d) => (sp.lo(), d.delim),
-        };
-        let args = tok.joint().into();
-        match self.toks.next()? {
-            TokenTree::Token(_, Token::FatArrow) => {}
-            _ => return None,
-        }
-        let (mut hi, body) = match self.toks.next()? {
-            TokenTree::Token(..) => return None,
-            TokenTree::Delimited(sp, _) => {
-                let data = sp.data();
-                (
-                    data.hi,
-                    Span::new(data.lo + BytePos(1), data.hi - BytePos(1), data.ctxt),
-                )
-            }
-        };
-        if let Some(TokenTree::Token(sp, Token::Semi)) = self.toks.look_ahead(0) {
-            self.toks.next();
-            hi = sp.hi();
-        }
-        Some(MacroBranch {
-            span: mk_sp(lo, hi),
-            args_paren_kind,
-            args,
-            body,
-        })
-    }
-}
-
-// A parsed macros 2.0 macro definition.
-struct Macro {
-    branches: Vec<MacroBranch>,
-}
-
-// FIXME: it would be more efficient to use references to the token streams
-// rather than clone them, if we can make the borrowing work out.
-struct MacroBranch {
-    span: Span,
-    args_paren_kind: DelimToken,
-    args: ThinTokenStream,
-    body: Span,
-}
-
-impl MacroBranch {
-    fn rewrite(
-        &self,
-        context: &RewriteContext,
-        shape: Shape,
-        multi_branch_style: bool,
-    ) -> Option<String> {
-        // Only attempt to format function-like macros.
-        if self.args_paren_kind != DelimToken::Paren {
-            // FIXME(#1539): implement for non-sugared macros.
-            return None;
-        }
-
-        let mut result = format_macro_args(self.args.clone())?;
-
-        if multi_branch_style {
-            result += " =>";
-        }
-
-        // The macro body is the most interesting part. It might end up as various
-        // AST nodes, but also has special variables (e.g, `$foo`) which can't be
-        // parsed as regular Rust code (and note that these can be escaped using
-        // `$$`). We'll try and format like an AST node, but we'll substitute
-        // variables for new names with the same length first.
-
-        let old_body = context.snippet(self.body).trim();
-        let (body_str, substs) = replace_names(old_body)?;
-
-        let mut config = context.config.clone();
-        config.set().hide_parse_errors(true);
-
-        result += " {";
-
-        let has_block_body = old_body.starts_with('{');
-
-        let body_indent = if has_block_body {
-            shape.indent
-        } else {
-            // We'll hack the indent below, take this into account when formatting,
-            let body_indent = shape.indent.block_indent(&config);
-            let new_width = config.max_width() - body_indent.width();
-            config.set().max_width(new_width);
-            body_indent
-        };
-
-        // First try to format as items, then as statements.
-        let new_body = match ::format_snippet(&body_str, &config) {
-            Some(new_body) => new_body,
-            None => match ::format_code_block(&body_str, &config) {
-                Some(new_body) => new_body,
-                None => return None,
-            },
-        };
-
-        // Indent the body since it is in a block.
-        let indent_str = body_indent.to_string(&config);
-        let mut new_body = new_body
-            .trim_right()
-            .lines()
-            .fold(String::new(), |mut s, l| {
-                if !l.is_empty() {
-                    s += &indent_str;
-                }
-                s + l + "\n"
-            });
-
-        // Undo our replacement of macro variables.
-        // FIXME: this could be *much* more efficient.
-        for (old, new) in &substs {
-            if old_body.find(new).is_some() {
-                debug!("rewrite_macro_def: bailing matching variable: `{}`", new);
-                return None;
-            }
-            new_body = new_body.replace(new, old);
-        }
-
-        if has_block_body {
-            result += new_body.trim();
-        } else if !new_body.is_empty() {
-            result += "\n";
-            result += &new_body;
-            result += &shape.indent.to_string(&config);
-        }
-
-        result += "}";
-
-        Some(result)
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use super::*;
-    use syntax::parse::{parse_stream_from_source_str, ParseSess};
-    use syntax::codemap::{FileName, FilePathMapping};
-
-    fn format_macro_args_str(s: &str) -> String {
-        let input = parse_stream_from_source_str(
-            FileName::Custom("stdin".to_owned()),
-            s.to_owned(),
-            &ParseSess::new(FilePathMapping::empty()),
-            None,
-        );
-        format_macro_args(input.into()).unwrap()
-    }
-
-    #[test]
-    fn test_format_macro_args() {
-        assert_eq!(format_macro_args_str(""), "".to_owned());
-        assert_eq!(format_macro_args_str("$ x : ident"), "$x: ident".to_owned());
-        assert_eq!(
-            format_macro_args_str("$ m1 : ident , $ m2 : ident , $ x : ident"),
-            "$m1: ident, $m2: ident, $x: ident".to_owned()
-        );
-        assert_eq!(
-            format_macro_args_str("$($beginning:ident),*;$middle:ident;$($end:ident),*"),
-            "$($beginning: ident),*; $middle: ident; $($end: ident),*".to_owned()
-        );
-        assert_eq!(
-            format_macro_args_str(
-                "$ name : ident ( $ ( $ dol : tt $ var : ident ) * ) $ ( $ body : tt ) *"
-            ),
-            "$name: ident($($dol: tt $var: ident)*) $($body: tt)*".to_owned()
-        );
-    }
-}
diff --git a/src/missed_spans.rs b/src/missed_spans.rs
deleted file mode 100644
index dff6b94bd75..00000000000
--- a/src/missed_spans.rs
+++ /dev/null
@@ -1,312 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::borrow::Cow;
-use std::iter::repeat;
-
-use syntax::codemap::{BytePos, FileName, Pos, Span};
-
-use codemap::LineRangeUtils;
-use comment::{rewrite_comment, CodeCharKind, CommentCodeSlices};
-use config::WriteMode;
-use shape::{Indent, Shape};
-use utils::{count_newlines, last_line_width, mk_sp};
-use visitor::FmtVisitor;
-
-struct SnippetStatus {
-    /// An offset to the current line from the beginnig of the original snippet.
-    line_start: usize,
-    /// A length of trailing whitespaces on the current line.
-    last_wspace: Option<usize>,
-    /// The current line number.
-    cur_line: usize,
-}
-
-impl SnippetStatus {
-    fn new(cur_line: usize) -> Self {
-        SnippetStatus {
-            line_start: 0,
-            last_wspace: None,
-            cur_line,
-        }
-    }
-}
-
-impl<'a> FmtVisitor<'a> {
-    fn output_at_start(&self) -> bool {
-        self.buffer.is_empty()
-    }
-
-    // TODO these format_missing methods are ugly. Refactor and add unit tests
-    // for the central whitespace stripping loop.
-    pub fn format_missing(&mut self, end: BytePos) {
-        self.format_missing_inner(end, |this, last_snippet, _| this.push_str(last_snippet))
-    }
-
-    pub fn format_missing_with_indent(&mut self, end: BytePos) {
-        let config = self.config;
-        self.format_missing_inner(end, |this, last_snippet, snippet| {
-            this.push_str(last_snippet.trim_right());
-            if last_snippet == snippet && !this.output_at_start() {
-                // No new lines in the snippet.
-                this.push_str("\n");
-            }
-            let indent = this.block_indent.to_string(config);
-            this.push_str(&indent);
-        })
-    }
-
-    pub fn format_missing_no_indent(&mut self, end: BytePos) {
-        self.format_missing_inner(end, |this, last_snippet, _| {
-            this.push_str(last_snippet.trim_right());
-        })
-    }
-
-    fn format_missing_inner<F: Fn(&mut FmtVisitor, &str, &str)>(
-        &mut self,
-        end: BytePos,
-        process_last_snippet: F,
-    ) {
-        let start = self.last_pos;
-
-        if start == end {
-            // Do nothing if this is the beginning of the file.
-            if !self.output_at_start() {
-                process_last_snippet(self, "", "");
-            }
-            return;
-        }
-
-        assert!(
-            start < end,
-            "Request to format inverted span: {:?} to {:?}",
-            self.codemap.lookup_char_pos(start),
-            self.codemap.lookup_char_pos(end)
-        );
-
-        self.last_pos = end;
-        let span = mk_sp(start, end);
-        let snippet = self.snippet(span);
-        if snippet.trim().is_empty() && !out_of_file_lines_range!(self, span) {
-            // Keep vertical spaces within range.
-            self.push_vertical_spaces(count_newlines(snippet));
-            process_last_snippet(self, "", snippet);
-        } else {
-            self.write_snippet(span, &process_last_snippet);
-        }
-    }
-
-    fn push_vertical_spaces(&mut self, mut newline_count: usize) {
-        // The buffer already has a trailing newline.
-        let offset = if self.buffer.ends_with('\n') { 0 } else { 1 };
-        let newline_upper_bound = self.config.blank_lines_upper_bound() + offset;
-        let newline_lower_bound = self.config.blank_lines_lower_bound() + offset;
-        if newline_count > newline_upper_bound {
-            newline_count = newline_upper_bound;
-        } else if newline_count < newline_lower_bound {
-            newline_count = newline_lower_bound;
-        }
-        let blank_lines: String = repeat('\n').take(newline_count).collect();
-        self.push_str(&blank_lines);
-    }
-
-    fn write_snippet<F>(&mut self, span: Span, process_last_snippet: F)
-    where
-        F: Fn(&mut FmtVisitor, &str, &str),
-    {
-        // Get a snippet from the file start to the span's hi without allocating.
-        // We need it to determine what precedes the current comment. If the comment
-        // follows code on the same line, we won't touch it.
-        let big_span_lo = self.codemap.lookup_char_pos(span.lo()).file.start_pos;
-        let local_begin = self.codemap.lookup_byte_offset(big_span_lo);
-        let local_end = self.codemap.lookup_byte_offset(span.hi());
-        let start_index = local_begin.pos.to_usize();
-        let end_index = local_end.pos.to_usize();
-        let big_snippet = &local_begin.fm.src.as_ref().unwrap()[start_index..end_index];
-
-        let big_diff = (span.lo() - big_span_lo).to_usize();
-        let snippet = self.snippet(span);
-
-        debug!("write_snippet `{}`", snippet);
-
-        self.write_snippet_inner(big_snippet, big_diff, snippet, span, process_last_snippet);
-    }
-
-    fn write_snippet_inner<F>(
-        &mut self,
-        big_snippet: &str,
-        big_diff: usize,
-        old_snippet: &str,
-        span: Span,
-        process_last_snippet: F,
-    ) where
-        F: Fn(&mut FmtVisitor, &str, &str),
-    {
-        // Trim whitespace from the right hand side of each line.
-        // Annoyingly, the library functions for splitting by lines etc. are not
-        // quite right, so we must do it ourselves.
-        let char_pos = self.codemap.lookup_char_pos(span.lo());
-        let file_name = &char_pos.file.name;
-        let mut status = SnippetStatus::new(char_pos.line);
-
-        let snippet = &*match self.config.write_mode() {
-            WriteMode::Coverage => replace_chars(old_snippet),
-            _ => Cow::from(old_snippet),
-        };
-
-        for (kind, offset, subslice) in CommentCodeSlices::new(snippet) {
-            debug!("{:?}: {:?}", kind, subslice);
-
-            let newline_count = count_newlines(subslice);
-            let within_file_lines_range = self.config.file_lines().intersects_range(
-                file_name,
-                status.cur_line,
-                status.cur_line + newline_count,
-            );
-
-            if CodeCharKind::Comment == kind && within_file_lines_range {
-                // 1: comment.
-                self.process_comment(
-                    &mut status,
-                    snippet,
-                    &big_snippet[..(offset + big_diff)],
-                    offset,
-                    subslice,
-                );
-            } else if subslice.trim().is_empty() && newline_count > 0 && within_file_lines_range {
-                // 2: blank lines.
-                self.push_vertical_spaces(newline_count);
-                status.cur_line += newline_count;
-                status.line_start = offset + newline_count;
-            } else {
-                // 3: code which we failed to format or which is not within file-lines range.
-                self.process_missing_code(&mut status, snippet, subslice, offset, file_name);
-            }
-        }
-
-        process_last_snippet(self, &snippet[status.line_start..], snippet);
-    }
-
-    fn process_comment(
-        &mut self,
-        status: &mut SnippetStatus,
-        snippet: &str,
-        big_snippet: &str,
-        offset: usize,
-        subslice: &str,
-    ) {
-        let last_char = big_snippet
-            .chars()
-            .rev()
-            .skip_while(|rev_c| [' ', '\t'].contains(rev_c))
-            .next();
-
-        let fix_indent = last_char.map_or(true, |rev_c| ['{', '\n'].contains(&rev_c));
-
-        let comment_indent = if fix_indent {
-            if let Some('{') = last_char {
-                self.push_str("\n");
-            }
-            let indent_str = self.block_indent.to_string(self.config);
-            self.push_str(&indent_str);
-            self.block_indent
-        } else {
-            self.push_str(" ");
-            Indent::from_width(self.config, last_line_width(&self.buffer))
-        };
-
-        let comment_width = ::std::cmp::min(
-            self.config.comment_width(),
-            self.config.max_width() - self.block_indent.width(),
-        );
-        let comment_shape = Shape::legacy(comment_width, comment_indent);
-        let comment_str = rewrite_comment(subslice, false, comment_shape, self.config)
-            .unwrap_or_else(|| String::from(subslice));
-        self.push_str(&comment_str);
-
-        status.last_wspace = None;
-        status.line_start = offset + subslice.len();
-
-        if let Some('/') = subslice.chars().nth(1) {
-            // check that there are no contained block comments
-            if !subslice
-                .split('\n')
-                .map(|s| s.trim_left())
-                .any(|s| s.len() >= 2 && &s[0..2] == "/*")
-            {
-                // Add a newline after line comments
-                self.push_str("\n");
-            }
-        } else if status.line_start <= snippet.len() {
-            // For other comments add a newline if there isn't one at the end already
-            match snippet[status.line_start..].chars().next() {
-                Some('\n') | Some('\r') => (),
-                _ => self.push_str("\n"),
-            }
-        }
-
-        status.cur_line += count_newlines(subslice);
-    }
-
-    fn process_missing_code(
-        &mut self,
-        status: &mut SnippetStatus,
-        snippet: &str,
-        subslice: &str,
-        offset: usize,
-        file_name: &FileName,
-    ) {
-        for (mut i, c) in subslice.char_indices() {
-            i += offset;
-
-            if c == '\n' {
-                let skip_this_line = !self.config
-                    .file_lines()
-                    .contains_line(file_name, status.cur_line);
-                if skip_this_line {
-                    status.last_wspace = None;
-                }
-
-                if let Some(lw) = status.last_wspace {
-                    self.push_str(&snippet[status.line_start..lw]);
-                    self.push_str("\n");
-                    status.last_wspace = None;
-                } else {
-                    self.push_str(&snippet[status.line_start..i + 1]);
-                }
-
-                status.cur_line += 1;
-                status.line_start = i + 1;
-            } else if c.is_whitespace() && status.last_wspace.is_none() {
-                status.last_wspace = Some(i);
-            } else if c == ';' && status.last_wspace.is_some() {
-                status.line_start = i;
-                status.last_wspace = None;
-            } else {
-                status.last_wspace = None;
-            }
-        }
-
-        let remaining = snippet[status.line_start..subslice.len() + offset].trim();
-        if !remaining.is_empty() {
-            self.push_str(remaining);
-            status.line_start = subslice.len() + offset;
-        }
-    }
-}
-
-fn replace_chars(string: &str) -> Cow<str> {
-    Cow::from(
-        string
-            .chars()
-            .map(|ch| if ch.is_whitespace() { ch } else { 'X' })
-            .collect::<String>(),
-    )
-}
diff --git a/src/modules.rs b/src/modules.rs
deleted file mode 100644
index 0f439910324..00000000000
--- a/src/modules.rs
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::collections::BTreeMap;
-use std::io;
-use std::path::{Path, PathBuf};
-
-use syntax::ast;
-use syntax::codemap::{self, FileName};
-use syntax::parse::parser;
-
-use utils::contains_skip;
-
-/// List all the files containing modules of a crate.
-/// If a file is used twice in a crate, it appears only once.
-pub fn list_files<'a>(
-    krate: &'a ast::Crate,
-    codemap: &codemap::CodeMap,
-) -> Result<BTreeMap<FileName, &'a ast::Mod>, io::Error> {
-    let mut result = BTreeMap::new(); // Enforce file order determinism
-    let root_filename = codemap.span_to_filename(krate.span);
-    {
-        let parent = match root_filename {
-            FileName::Real(ref path) => path.parent().unwrap(),
-            _ => Path::new(""),
-        };
-        list_submodules(&krate.module, parent, codemap, &mut result)?;
-    }
-    result.insert(root_filename, &krate.module);
-    Ok(result)
-}
-
-/// Recursively list all external modules included in a module.
-fn list_submodules<'a>(
-    module: &'a ast::Mod,
-    search_dir: &Path,
-    codemap: &codemap::CodeMap,
-    result: &mut BTreeMap<FileName, &'a ast::Mod>,
-) -> Result<(), io::Error> {
-    debug!("list_submodules: search_dir: {:?}", search_dir);
-    for item in &module.items {
-        if let ast::ItemKind::Mod(ref sub_mod) = item.node {
-            if !contains_skip(&item.attrs) {
-                let is_internal =
-                    codemap.span_to_filename(item.span) == codemap.span_to_filename(sub_mod.inner);
-                let dir_path = if is_internal {
-                    search_dir.join(&item.ident.to_string())
-                } else {
-                    let mod_path = module_file(item.ident, &item.attrs, search_dir, codemap)?;
-                    let dir_path = mod_path.parent().unwrap().to_owned();
-                    result.insert(FileName::Real(mod_path), sub_mod);
-                    dir_path
-                };
-                list_submodules(sub_mod, &dir_path, codemap, result)?;
-            }
-        }
-    }
-    Ok(())
-}
-
-/// Find the file corresponding to an external mod
-fn module_file(
-    id: ast::Ident,
-    attrs: &[ast::Attribute],
-    dir_path: &Path,
-    codemap: &codemap::CodeMap,
-) -> Result<PathBuf, io::Error> {
-    if let Some(path) = parser::Parser::submod_path_from_attr(attrs, dir_path) {
-        return Ok(path);
-    }
-
-    match parser::Parser::default_submod_path(id, None, dir_path, codemap).result {
-        Ok(parser::ModulePathSuccess { path, .. }) => Ok(path),
-        Err(_) => Err(io::Error::new(
-            io::ErrorKind::Other,
-            format!("Couldn't find module {}", id),
-        )),
-    }
-}
diff --git a/src/patterns.rs b/src/patterns.rs
deleted file mode 100644
index 4719160061b..00000000000
--- a/src/patterns.rs
+++ /dev/null
@@ -1,379 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use syntax::ast::{self, BindingMode, FieldPat, Pat, PatKind, RangeEnd, RangeSyntax};
-use syntax::codemap::{self, BytePos, Span};
-use syntax::ptr;
-
-use codemap::SpanUtils;
-use comment::FindUncommented;
-use expr::{can_be_overflowed_expr, rewrite_call_inner, rewrite_pair, rewrite_unary_prefix,
-           wrap_struct_field, PairParts};
-use lists::{itemize_list, shape_for_tactic, struct_lit_formatting, struct_lit_shape,
-            struct_lit_tactic, write_list, DefinitiveListTactic, SeparatorPlace, SeparatorTactic};
-use macros::{rewrite_macro, MacroPosition};
-use rewrite::{Rewrite, RewriteContext};
-use shape::Shape;
-use spanned::Spanned;
-use types::{rewrite_path, PathContext};
-use utils::{format_mutability, mk_sp};
-
-impl Rewrite for Pat {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        match self.node {
-            PatKind::Box(ref pat) => rewrite_unary_prefix(context, "box ", &**pat, shape),
-            PatKind::Ident(binding_mode, ident, ref sub_pat) => {
-                let (prefix, mutability) = match binding_mode {
-                    BindingMode::ByRef(mutability) => ("ref ", mutability),
-                    BindingMode::ByValue(mutability) => ("", mutability),
-                };
-                let mut_infix = format_mutability(mutability);
-                let id_str = ident.node.to_string();
-                let sub_pat = match *sub_pat {
-                    Some(ref p) => {
-                        // 3 - ` @ `.
-                        let width = shape
-                            .width
-                            .checked_sub(prefix.len() + mut_infix.len() + id_str.len() + 3)?;
-                        format!(
-                            " @ {}",
-                            p.rewrite(context, Shape::legacy(width, shape.indent))?
-                        )
-                    }
-                    None => "".to_owned(),
-                };
-
-                Some(format!("{}{}{}{}", prefix, mut_infix, id_str, sub_pat))
-            }
-            PatKind::Wild => {
-                if 1 <= shape.width {
-                    Some("_".to_owned())
-                } else {
-                    None
-                }
-            }
-            PatKind::Range(ref lhs, ref rhs, ref end_kind) => {
-                let infix = match *end_kind {
-                    RangeEnd::Included(RangeSyntax::DotDotDot) => "...",
-                    RangeEnd::Included(RangeSyntax::DotDotEq) => "..=",
-                    RangeEnd::Excluded => "..",
-                };
-                let infix = if context.config.spaces_around_ranges() {
-                    format!(" {} ", infix)
-                } else {
-                    infix.to_owned()
-                };
-                rewrite_pair(
-                    &**lhs,
-                    &**rhs,
-                    PairParts::new("", &infix, ""),
-                    context,
-                    shape,
-                    SeparatorPlace::Front,
-                )
-            }
-            PatKind::Ref(ref pat, mutability) => {
-                let prefix = format!("&{}", format_mutability(mutability));
-                rewrite_unary_prefix(context, &prefix, &**pat, shape)
-            }
-            PatKind::Tuple(ref items, dotdot_pos) => {
-                rewrite_tuple_pat(items, dotdot_pos, None, self.span, context, shape)
-            }
-            PatKind::Path(ref q_self, ref path) => {
-                rewrite_path(context, PathContext::Expr, q_self.as_ref(), path, shape)
-            }
-            PatKind::TupleStruct(ref path, ref pat_vec, dotdot_pos) => {
-                let path_str = rewrite_path(context, PathContext::Expr, None, path, shape)?;
-                rewrite_tuple_pat(
-                    pat_vec,
-                    dotdot_pos,
-                    Some(path_str),
-                    self.span,
-                    context,
-                    shape,
-                )
-            }
-            PatKind::Lit(ref expr) => expr.rewrite(context, shape),
-            PatKind::Slice(ref prefix, ref slice_pat, ref suffix) => {
-                // Rewrite all the sub-patterns.
-                let prefix = prefix.iter().map(|p| p.rewrite(context, shape));
-                let slice_pat = slice_pat
-                    .as_ref()
-                    .map(|p| Some(format!("{}..", p.rewrite(context, shape)?)));
-                let suffix = suffix.iter().map(|p| p.rewrite(context, shape));
-
-                // Munge them together.
-                let pats: Option<Vec<String>> =
-                    prefix.chain(slice_pat.into_iter()).chain(suffix).collect();
-
-                // Check that all the rewrites succeeded, and if not return None.
-                let pats = pats?;
-
-                // Unwrap all the sub-strings and join them with commas.
-                let result = if context.config.spaces_within_parens_and_brackets() {
-                    format!("[ {} ]", pats.join(", "))
-                } else {
-                    format!("[{}]", pats.join(", "))
-                };
-                Some(result)
-            }
-            PatKind::Struct(ref path, ref fields, ellipsis) => {
-                rewrite_struct_pat(path, fields, ellipsis, self.span, context, shape)
-            }
-            PatKind::Mac(ref mac) => rewrite_macro(mac, None, context, shape, MacroPosition::Pat),
-        }
-    }
-}
-
-fn rewrite_struct_pat(
-    path: &ast::Path,
-    fields: &[codemap::Spanned<ast::FieldPat>],
-    ellipsis: bool,
-    span: Span,
-    context: &RewriteContext,
-    shape: Shape,
-) -> Option<String> {
-    // 2 =  ` {`
-    let path_shape = shape.sub_width(2)?;
-    let path_str = rewrite_path(context, PathContext::Expr, None, path, path_shape)?;
-
-    if fields.is_empty() && !ellipsis {
-        return Some(format!("{} {{}}", path_str));
-    }
-
-    let (ellipsis_str, terminator) = if ellipsis { (", ..", "..") } else { ("", "}") };
-
-    // 3 = ` { `, 2 = ` }`.
-    let (h_shape, v_shape) =
-        struct_lit_shape(shape, context, path_str.len() + 3, ellipsis_str.len() + 2)?;
-
-    let items = itemize_list(
-        context.codemap,
-        fields.iter(),
-        terminator,
-        ",",
-        |f| f.span.lo(),
-        |f| f.span.hi(),
-        |f| f.node.rewrite(context, v_shape),
-        context.codemap.span_after(span, "{"),
-        span.hi(),
-        false,
-    );
-    let item_vec = items.collect::<Vec<_>>();
-
-    let tactic = struct_lit_tactic(h_shape, context, &item_vec);
-    let nested_shape = shape_for_tactic(tactic, h_shape, v_shape);
-    let fmt = struct_lit_formatting(nested_shape, tactic, context, false);
-
-    let mut fields_str = write_list(&item_vec, &fmt)?;
-    let one_line_width = h_shape.map_or(0, |shape| shape.width);
-
-    if ellipsis {
-        if fields_str.contains('\n') || fields_str.len() > one_line_width {
-            // Add a missing trailing comma.
-            if fmt.trailing_separator == SeparatorTactic::Never {
-                fields_str.push_str(",");
-            }
-            fields_str.push_str("\n");
-            fields_str.push_str(&nested_shape.indent.to_string(context.config));
-            fields_str.push_str("..");
-        } else {
-            if !fields_str.is_empty() {
-                // there are preceding struct fields being matched on
-                if fmt.tactic == DefinitiveListTactic::Vertical {
-                    // if the tactic is Vertical, write_list already added a trailing ,
-                    fields_str.push_str(" ");
-                } else {
-                    fields_str.push_str(", ");
-                }
-            }
-            fields_str.push_str("..");
-        }
-    }
-
-    let fields_str = wrap_struct_field(context, &fields_str, shape, v_shape, one_line_width);
-    Some(format!("{} {{{}}}", path_str, fields_str))
-}
-
-impl Rewrite for FieldPat {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        let pat = self.pat.rewrite(context, shape);
-        if self.is_shorthand {
-            pat
-        } else {
-            let pat_str = pat?;
-            let id_str = self.ident.to_string();
-            let one_line_width = id_str.len() + 2 + pat_str.len();
-            if one_line_width <= shape.width {
-                Some(format!("{}: {}", id_str, pat_str))
-            } else {
-                let nested_shape = shape.block_indent(context.config.tab_spaces());
-                let pat_str = self.pat.rewrite(context, nested_shape)?;
-                Some(format!(
-                    "{}:\n{}{}",
-                    id_str,
-                    nested_shape.indent.to_string(context.config),
-                    pat_str,
-                ))
-            }
-        }
-    }
-}
-
-pub enum TuplePatField<'a> {
-    Pat(&'a ptr::P<ast::Pat>),
-    Dotdot(Span),
-}
-
-impl<'a> Rewrite for TuplePatField<'a> {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        match *self {
-            TuplePatField::Pat(p) => p.rewrite(context, shape),
-            TuplePatField::Dotdot(_) => Some("..".to_string()),
-        }
-    }
-}
-
-impl<'a> Spanned for TuplePatField<'a> {
-    fn span(&self) -> Span {
-        match *self {
-            TuplePatField::Pat(p) => p.span(),
-            TuplePatField::Dotdot(span) => span,
-        }
-    }
-}
-
-pub fn can_be_overflowed_pat(context: &RewriteContext, pat: &TuplePatField, len: usize) -> bool {
-    match *pat {
-        TuplePatField::Pat(pat) => match pat.node {
-            ast::PatKind::Path(..)
-            | ast::PatKind::Tuple(..)
-            | ast::PatKind::Struct(..)
-            | ast::PatKind::TupleStruct(..) => context.use_block_indent() && len == 1,
-            ast::PatKind::Ref(ref p, _) | ast::PatKind::Box(ref p) => {
-                can_be_overflowed_pat(context, &TuplePatField::Pat(p), len)
-            }
-            ast::PatKind::Lit(ref expr) => can_be_overflowed_expr(context, expr, len),
-            _ => false,
-        },
-        TuplePatField::Dotdot(..) => false,
-    }
-}
-
-fn rewrite_tuple_pat(
-    pats: &[ptr::P<ast::Pat>],
-    dotdot_pos: Option<usize>,
-    path_str: Option<String>,
-    span: Span,
-    context: &RewriteContext,
-    shape: Shape,
-) -> Option<String> {
-    let mut pat_vec: Vec<_> = pats.into_iter().map(|x| TuplePatField::Pat(x)).collect();
-
-    if let Some(pos) = dotdot_pos {
-        let prev = if pos == 0 {
-            span.lo()
-        } else {
-            pats[pos - 1].span().hi()
-        };
-        let next = if pos + 1 >= pats.len() {
-            span.hi()
-        } else {
-            pats[pos + 1].span().lo()
-        };
-        let dot_span = mk_sp(prev, next);
-        let snippet = context.snippet(dot_span);
-        let lo = dot_span.lo() + BytePos(snippet.find_uncommented("..").unwrap() as u32);
-        let dotdot = TuplePatField::Dotdot(Span::new(
-            lo,
-            // 2 == "..".len()
-            lo + BytePos(2),
-            codemap::NO_EXPANSION,
-        ));
-        pat_vec.insert(pos, dotdot);
-    }
-
-    if pat_vec.is_empty() {
-        return Some(format!("{}()", path_str.unwrap_or_default()));
-    }
-
-    let wildcard_suffix_len = count_wildcard_suffix_len(context, &pat_vec, span, shape);
-    let (pat_vec, span) = if context.config.condense_wildcard_suffixes() && wildcard_suffix_len >= 2
-    {
-        let new_item_count = 1 + pat_vec.len() - wildcard_suffix_len;
-        let sp = pat_vec[new_item_count - 1].span();
-        let snippet = context.snippet(sp);
-        let lo = sp.lo() + BytePos(snippet.find_uncommented("_").unwrap() as u32);
-        pat_vec[new_item_count - 1] = TuplePatField::Dotdot(mk_sp(lo, lo + BytePos(1)));
-        (
-            &pat_vec[..new_item_count],
-            mk_sp(span.lo(), lo + BytePos(1)),
-        )
-    } else {
-        (&pat_vec[..], span)
-    };
-
-    // add comma if `(x,)`
-    let add_comma = path_str.is_none() && pat_vec.len() == 1 && dotdot_pos.is_none();
-    let mut context = context.clone();
-    if let Some(&TuplePatField::Dotdot(..)) = pat_vec.last() {
-        context.inside_macro = true;
-    }
-    let path_str = path_str.unwrap_or_default();
-    let mut pat_ref_vec = Vec::with_capacity(pat_vec.len());
-    for pat in pat_vec {
-        pat_ref_vec.push(pat);
-    }
-
-    rewrite_call_inner(
-        &context,
-        &path_str,
-        &pat_ref_vec[..],
-        span,
-        shape,
-        shape.width,
-        add_comma,
-    )
-}
-
-fn count_wildcard_suffix_len(
-    context: &RewriteContext,
-    patterns: &[TuplePatField],
-    span: Span,
-    shape: Shape,
-) -> usize {
-    let mut suffix_len = 0;
-
-    let items: Vec<_> = itemize_list(
-        context.codemap,
-        patterns.iter(),
-        ")",
-        ",",
-        |item| item.span().lo(),
-        |item| item.span().hi(),
-        |item| item.rewrite(context, shape),
-        context.codemap.span_after(span, "("),
-        span.hi() - BytePos(1),
-        false,
-    ).collect();
-
-    for item in items.iter().rev().take_while(|i| match i.item {
-        Some(ref internal_string) if internal_string == "_" => true,
-        _ => false,
-    }) {
-        suffix_len += 1;
-
-        if item.pre_comment.is_some() || item.post_comment.is_some() {
-            break;
-        }
-    }
-
-    suffix_len
-}
diff --git a/src/rewrite.rs b/src/rewrite.rs
deleted file mode 100644
index 708e31d86dd..00000000000
--- a/src/rewrite.rs
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// A generic trait to abstract the rewriting of an element (of the AST).
-
-use syntax::codemap::{CodeMap, Span};
-use syntax::parse::ParseSess;
-
-use config::{Config, IndentStyle};
-use shape::Shape;
-use visitor::SnippetProvider;
-
-pub trait Rewrite {
-    /// Rewrite self into shape.
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String>;
-}
-
-#[derive(Clone)]
-pub struct RewriteContext<'a> {
-    pub parse_session: &'a ParseSess,
-    pub codemap: &'a CodeMap,
-    pub config: &'a Config,
-    pub inside_macro: bool,
-    // Force block indent style even if we are using visual indent style.
-    pub use_block: bool,
-    // When `format_if_else_cond_comment` is true, unindent the comment on top
-    // of the `else` or `else if`.
-    pub is_if_else_block: bool,
-    // When rewriting chain, veto going multi line except the last element
-    pub force_one_line_chain: bool,
-    pub snippet_provider: &'a SnippetProvider<'a>,
-}
-
-impl<'a> RewriteContext<'a> {
-    pub fn snippet(&self, span: Span) -> &str {
-        self.snippet_provider.span_to_snippet(span).unwrap()
-    }
-
-    /// Return true if we should use block indent style for rewriting function call.
-    pub fn use_block_indent(&self) -> bool {
-        self.config.indent_style() == IndentStyle::Block || self.use_block
-    }
-
-    pub fn budget(&self, used_width: usize) -> usize {
-        self.config.max_width().checked_sub(used_width).unwrap_or(0)
-    }
-}
diff --git a/src/rustfmt_diff.rs b/src/rustfmt_diff.rs
deleted file mode 100644
index 1a2f570f89e..00000000000
--- a/src/rustfmt_diff.rs
+++ /dev/null
@@ -1,247 +0,0 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use config::Color;
-use diff;
-use std::collections::VecDeque;
-use std::io;
-use term;
-use utils::use_colored_tty;
-
-#[derive(Debug, PartialEq)]
-pub enum DiffLine {
-    Context(String),
-    Expected(String),
-    Resulting(String),
-}
-
-#[derive(Debug, PartialEq)]
-pub struct Mismatch {
-    pub line_number: u32,
-    pub lines: Vec<DiffLine>,
-}
-
-impl Mismatch {
-    fn new(line_number: u32) -> Mismatch {
-        Mismatch {
-            line_number,
-            lines: Vec::new(),
-        }
-    }
-}
-
-// This struct handles writing output to stdout and abstracts away the logic
-// of printing in color, if it's possible in the executing environment.
-pub struct OutputWriter {
-    terminal: Option<Box<term::Terminal<Output = io::Stdout>>>,
-}
-
-impl OutputWriter {
-    // Create a new OutputWriter instance based on the caller's preference
-    // for colorized output and the capabilities of the terminal.
-    pub fn new(color: Color) -> Self {
-        if let Some(t) = term::stdout() {
-            if use_colored_tty(color) && t.supports_color() {
-                return OutputWriter { terminal: Some(t) };
-            }
-        }
-        OutputWriter { terminal: None }
-    }
-
-    // Write output in the optionally specified color. The output is written
-    // in the specified color if this OutputWriter instance contains a
-    // Terminal in its `terminal` field.
-    pub fn writeln(&mut self, msg: &str, color: Option<term::color::Color>) {
-        match &mut self.terminal {
-            Some(ref mut t) => {
-                if let Some(color) = color {
-                    t.fg(color).unwrap();
-                }
-                writeln!(t, "{}", msg).unwrap();
-                if color.is_some() {
-                    t.reset().unwrap();
-                }
-            }
-            None => println!("{}", msg),
-        }
-    }
-}
-
-// Produces a diff between the expected output and actual output of rustfmt.
-pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec<Mismatch> {
-    let mut line_number = 1;
-    let mut context_queue: VecDeque<&str> = VecDeque::with_capacity(context_size);
-    let mut lines_since_mismatch = context_size + 1;
-    let mut results = Vec::new();
-    let mut mismatch = Mismatch::new(0);
-
-    for result in diff::lines(expected, actual) {
-        match result {
-            diff::Result::Left(str) => {
-                if lines_since_mismatch >= context_size && lines_since_mismatch > 0 {
-                    results.push(mismatch);
-                    mismatch = Mismatch::new(line_number - context_queue.len() as u32);
-                }
-
-                while let Some(line) = context_queue.pop_front() {
-                    mismatch.lines.push(DiffLine::Context(line.to_owned()));
-                }
-
-                mismatch.lines.push(DiffLine::Resulting(str.to_owned()));
-                lines_since_mismatch = 0;
-            }
-            diff::Result::Right(str) => {
-                if lines_since_mismatch >= context_size && lines_since_mismatch > 0 {
-                    results.push(mismatch);
-                    mismatch = Mismatch::new(line_number - context_queue.len() as u32);
-                }
-
-                while let Some(line) = context_queue.pop_front() {
-                    mismatch.lines.push(DiffLine::Context(line.to_owned()));
-                }
-
-                mismatch.lines.push(DiffLine::Expected(str.to_owned()));
-                line_number += 1;
-                lines_since_mismatch = 0;
-            }
-            diff::Result::Both(str, _) => {
-                if context_queue.len() >= context_size {
-                    let _ = context_queue.pop_front();
-                }
-
-                if lines_since_mismatch < context_size {
-                    mismatch.lines.push(DiffLine::Context(str.to_owned()));
-                } else if context_size > 0 {
-                    context_queue.push_back(str);
-                }
-
-                line_number += 1;
-                lines_since_mismatch += 1;
-            }
-        }
-    }
-
-    results.push(mismatch);
-    results.remove(0);
-
-    results
-}
-
-pub fn print_diff<F>(diff: Vec<Mismatch>, get_section_title: F, color: Color)
-where
-    F: Fn(u32) -> String,
-{
-    let mut writer = OutputWriter::new(color);
-
-    for mismatch in diff {
-        let title = get_section_title(mismatch.line_number);
-        writer.writeln(&format!("{}", title), None);
-
-        for line in mismatch.lines {
-            match line {
-                DiffLine::Context(ref str) => writer.writeln(&format!(" {}⏎", str), None),
-                DiffLine::Expected(ref str) => {
-                    writer.writeln(&format!("+{}⏎", str), Some(term::color::GREEN))
-                }
-                DiffLine::Resulting(ref str) => {
-                    writer.writeln(&format!("-{}⏎", str), Some(term::color::RED))
-                }
-            }
-        }
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use super::{make_diff, Mismatch};
-    use super::DiffLine::*;
-
-    #[test]
-    fn diff_simple() {
-        let src = "one\ntwo\nthree\nfour\nfive\n";
-        let dest = "one\ntwo\ntrois\nfour\nfive\n";
-        let diff = make_diff(src, dest, 1);
-        assert_eq!(
-            diff,
-            vec![
-                Mismatch {
-                    line_number: 2,
-                    lines: vec![
-                        Context("two".to_owned()),
-                        Resulting("three".to_owned()),
-                        Expected("trois".to_owned()),
-                        Context("four".to_owned()),
-                    ],
-                },
-            ]
-        );
-    }
-
-    #[test]
-    fn diff_simple2() {
-        let src = "one\ntwo\nthree\nfour\nfive\nsix\nseven\n";
-        let dest = "one\ntwo\ntrois\nfour\ncinq\nsix\nseven\n";
-        let diff = make_diff(src, dest, 1);
-        assert_eq!(
-            diff,
-            vec![
-                Mismatch {
-                    line_number: 2,
-                    lines: vec![
-                        Context("two".to_owned()),
-                        Resulting("three".to_owned()),
-                        Expected("trois".to_owned()),
-                        Context("four".to_owned()),
-                    ],
-                },
-                Mismatch {
-                    line_number: 5,
-                    lines: vec![
-                        Resulting("five".to_owned()),
-                        Expected("cinq".to_owned()),
-                        Context("six".to_owned()),
-                    ],
-                },
-            ]
-        );
-    }
-
-    #[test]
-    fn diff_zerocontext() {
-        let src = "one\ntwo\nthree\nfour\nfive\n";
-        let dest = "one\ntwo\ntrois\nfour\nfive\n";
-        let diff = make_diff(src, dest, 0);
-        assert_eq!(
-            diff,
-            vec![
-                Mismatch {
-                    line_number: 3,
-                    lines: vec![Resulting("three".to_owned()), Expected("trois".to_owned())],
-                },
-            ]
-        );
-    }
-
-    #[test]
-    fn diff_trailing_newline() {
-        let src = "one\ntwo\nthree\nfour\nfive";
-        let dest = "one\ntwo\nthree\nfour\nfive\n";
-        let diff = make_diff(src, dest, 1);
-        assert_eq!(
-            diff,
-            vec![
-                Mismatch {
-                    line_number: 5,
-                    lines: vec![Context("five".to_owned()), Expected("".to_owned())],
-                },
-            ]
-        );
-    }
-}
diff --git a/src/shape.rs b/src/shape.rs
deleted file mode 100644
index 8fe2e2b18c0..00000000000
--- a/src/shape.rs
+++ /dev/null
@@ -1,353 +0,0 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::borrow::Cow;
-use std::ops::{Add, Sub};
-
-use Config;
-
-#[derive(Copy, Clone, Debug)]
-pub struct Indent {
-    // Width of the block indent, in characters. Must be a multiple of
-    // Config::tab_spaces.
-    pub block_indent: usize,
-    // Alignment in characters.
-    pub alignment: usize,
-}
-
-// INDENT_BUFFER.len() = 80
-const INDENT_BUFFER_LEN: usize = 80;
-const INDENT_BUFFER: &str =
-    "                                                                                ";
-impl Indent {
-    pub fn new(block_indent: usize, alignment: usize) -> Indent {
-        Indent {
-            block_indent,
-            alignment,
-        }
-    }
-
-    pub fn from_width(config: &Config, width: usize) -> Indent {
-        if config.hard_tabs() {
-            let tab_num = width / config.tab_spaces();
-            let alignment = width % config.tab_spaces();
-            Indent::new(config.tab_spaces() * tab_num, alignment)
-        } else {
-            Indent::new(width, 0)
-        }
-    }
-
-    pub fn empty() -> Indent {
-        Indent::new(0, 0)
-    }
-
-    pub fn block_only(&self) -> Indent {
-        Indent {
-            block_indent: self.block_indent,
-            alignment: 0,
-        }
-    }
-
-    pub fn block_indent(mut self, config: &Config) -> Indent {
-        self.block_indent += config.tab_spaces();
-        self
-    }
-
-    pub fn block_unindent(mut self, config: &Config) -> Indent {
-        if self.block_indent < config.tab_spaces() {
-            Indent::new(self.block_indent, 0)
-        } else {
-            self.block_indent -= config.tab_spaces();
-            self
-        }
-    }
-
-    pub fn width(&self) -> usize {
-        self.block_indent + self.alignment
-    }
-
-    pub fn to_string(&self, config: &Config) -> Cow<'static, str> {
-        let (num_tabs, num_spaces) = if config.hard_tabs() {
-            (self.block_indent / config.tab_spaces(), self.alignment)
-        } else {
-            (0, self.width())
-        };
-        let num_chars = num_tabs + num_spaces;
-        if num_tabs == 0 && num_chars <= INDENT_BUFFER_LEN {
-            Cow::from(&INDENT_BUFFER[0..num_chars])
-        } else {
-            let mut indent = String::with_capacity(num_chars);
-            for _ in 0..num_tabs {
-                indent.push('\t')
-            }
-            for _ in 0..num_spaces {
-                indent.push(' ')
-            }
-            Cow::from(indent)
-        }
-    }
-}
-
-impl Add for Indent {
-    type Output = Indent;
-
-    fn add(self, rhs: Indent) -> Indent {
-        Indent {
-            block_indent: self.block_indent + rhs.block_indent,
-            alignment: self.alignment + rhs.alignment,
-        }
-    }
-}
-
-impl Sub for Indent {
-    type Output = Indent;
-
-    fn sub(self, rhs: Indent) -> Indent {
-        Indent::new(
-            self.block_indent - rhs.block_indent,
-            self.alignment - rhs.alignment,
-        )
-    }
-}
-
-impl Add<usize> for Indent {
-    type Output = Indent;
-
-    fn add(self, rhs: usize) -> Indent {
-        Indent::new(self.block_indent, self.alignment + rhs)
-    }
-}
-
-impl Sub<usize> for Indent {
-    type Output = Indent;
-
-    fn sub(self, rhs: usize) -> Indent {
-        Indent::new(self.block_indent, self.alignment - rhs)
-    }
-}
-
-#[derive(Copy, Clone, Debug)]
-pub struct Shape {
-    pub width: usize,
-    // The current indentation of code.
-    pub indent: Indent,
-    // Indentation + any already emitted text on the first line of the current
-    // statement.
-    pub offset: usize,
-}
-
-impl Shape {
-    /// `indent` is the indentation of the first line. The next lines
-    /// should begin with at least `indent` spaces (except backwards
-    /// indentation). The first line should not begin with indentation.
-    /// `width` is the maximum number of characters on the last line
-    /// (excluding `indent`). The width of other lines is not limited by
-    /// `width`.
-    /// Note that in reality, we sometimes use width for lines other than the
-    /// last (i.e., we are conservative).
-    // .......*-------*
-    //        |       |
-    //        |     *-*
-    //        *-----|
-    // |<------------>|  max width
-    // |<---->|          indent
-    //        |<--->|    width
-    pub fn legacy(width: usize, indent: Indent) -> Shape {
-        Shape {
-            width,
-            indent,
-            offset: indent.alignment,
-        }
-    }
-
-    pub fn indented(indent: Indent, config: &Config) -> Shape {
-        Shape {
-            width: config.max_width().checked_sub(indent.width()).unwrap_or(0),
-            indent,
-            offset: indent.alignment,
-        }
-    }
-
-    pub fn with_max_width(&self, config: &Config) -> Shape {
-        Shape {
-            width: config
-                .max_width()
-                .checked_sub(self.indent.width())
-                .unwrap_or(0),
-            ..*self
-        }
-    }
-
-    pub fn offset(width: usize, indent: Indent, offset: usize) -> Shape {
-        Shape {
-            width,
-            indent,
-            offset,
-        }
-    }
-
-    pub fn visual_indent(&self, extra_width: usize) -> Shape {
-        let alignment = self.offset + extra_width;
-        Shape {
-            width: self.width,
-            indent: Indent::new(self.indent.block_indent, alignment),
-            offset: alignment,
-        }
-    }
-
-    pub fn block_indent(&self, extra_width: usize) -> Shape {
-        if self.indent.alignment == 0 {
-            Shape {
-                width: self.width,
-                indent: Indent::new(self.indent.block_indent + extra_width, 0),
-                offset: 0,
-            }
-        } else {
-            Shape {
-                width: self.width,
-                indent: self.indent + extra_width,
-                offset: self.indent.alignment + extra_width,
-            }
-        }
-    }
-
-    pub fn block_left(&self, width: usize) -> Option<Shape> {
-        self.block_indent(width).sub_width(width)
-    }
-
-    pub fn add_offset(&self, extra_width: usize) -> Shape {
-        Shape {
-            offset: self.offset + extra_width,
-            ..*self
-        }
-    }
-
-    pub fn block(&self) -> Shape {
-        Shape {
-            indent: self.indent.block_only(),
-            ..*self
-        }
-    }
-
-    pub fn sub_width(&self, width: usize) -> Option<Shape> {
-        Some(Shape {
-            width: self.width.checked_sub(width)?,
-            ..*self
-        })
-    }
-
-    pub fn shrink_left(&self, width: usize) -> Option<Shape> {
-        Some(Shape {
-            width: self.width.checked_sub(width)?,
-            indent: self.indent + width,
-            offset: self.offset + width,
-        })
-    }
-
-    pub fn offset_left(&self, width: usize) -> Option<Shape> {
-        self.add_offset(width).sub_width(width)
-    }
-
-    pub fn used_width(&self) -> usize {
-        self.indent.block_indent + self.offset
-    }
-
-    pub fn rhs_overhead(&self, config: &Config) -> usize {
-        config
-            .max_width()
-            .checked_sub(self.used_width() + self.width)
-            .unwrap_or(0)
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use super::*;
-
-    #[test]
-    fn indent_add_sub() {
-        let indent = Indent::new(4, 8) + Indent::new(8, 12);
-        assert_eq!(12, indent.block_indent);
-        assert_eq!(20, indent.alignment);
-
-        let indent = indent - Indent::new(4, 4);
-        assert_eq!(8, indent.block_indent);
-        assert_eq!(16, indent.alignment);
-    }
-
-    #[test]
-    fn indent_add_sub_alignment() {
-        let indent = Indent::new(4, 8) + 4;
-        assert_eq!(4, indent.block_indent);
-        assert_eq!(12, indent.alignment);
-
-        let indent = indent - 4;
-        assert_eq!(4, indent.block_indent);
-        assert_eq!(8, indent.alignment);
-    }
-
-    #[test]
-    fn indent_to_string_spaces() {
-        let config = Config::default();
-        let indent = Indent::new(4, 8);
-
-        // 12 spaces
-        assert_eq!("            ", indent.to_string(&config));
-    }
-
-    #[test]
-    fn indent_to_string_hard_tabs() {
-        let mut config = Config::default();
-        config.set().hard_tabs(true);
-        let indent = Indent::new(8, 4);
-
-        // 2 tabs + 4 spaces
-        assert_eq!("\t\t    ", indent.to_string(&config));
-    }
-
-    #[test]
-    fn shape_visual_indent() {
-        let config = Config::default();
-        let indent = Indent::new(4, 8);
-        let shape = Shape::legacy(config.max_width(), indent);
-        let shape = shape.visual_indent(20);
-
-        assert_eq!(config.max_width(), shape.width);
-        assert_eq!(4, shape.indent.block_indent);
-        assert_eq!(28, shape.indent.alignment);
-        assert_eq!(28, shape.offset);
-    }
-
-    #[test]
-    fn shape_block_indent_without_alignment() {
-        let config = Config::default();
-        let indent = Indent::new(4, 0);
-        let shape = Shape::legacy(config.max_width(), indent);
-        let shape = shape.block_indent(20);
-
-        assert_eq!(config.max_width(), shape.width);
-        assert_eq!(24, shape.indent.block_indent);
-        assert_eq!(0, shape.indent.alignment);
-        assert_eq!(0, shape.offset);
-    }
-
-    #[test]
-    fn shape_block_indent_with_alignment() {
-        let config = Config::default();
-        let indent = Indent::new(4, 8);
-        let shape = Shape::legacy(config.max_width(), indent);
-        let shape = shape.block_indent(20);
-
-        assert_eq!(config.max_width(), shape.width);
-        assert_eq!(4, shape.indent.block_indent);
-        assert_eq!(28, shape.indent.alignment);
-        assert_eq!(28, shape.offset);
-    }
-}
diff --git a/src/spanned.rs b/src/spanned.rs
deleted file mode 100644
index a431f3a544a..00000000000
--- a/src/spanned.rs
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use syntax::ast;
-use syntax::codemap::Span;
-
-use macros::MacroArg;
-use utils::{mk_sp, outer_attributes};
-
-/// Spanned returns a span including attributes, if available.
-pub trait Spanned {
-    fn span(&self) -> Span;
-}
-
-macro_rules! span_with_attrs_lo_hi {
-    ($this: ident, $lo: expr, $hi: expr) => {{
-        let attrs = outer_attributes(&$this.attrs);
-        if attrs.is_empty() {
-            mk_sp($lo, $hi)
-        } else {
-            mk_sp(attrs[0].span.lo(), $hi)
-        }
-    }};
-}
-
-macro_rules! span_with_attrs {
-    ($this: ident) => {
-        span_with_attrs_lo_hi!($this, $this.span.lo(), $this.span.hi())
-    };
-}
-
-macro_rules! implement_spanned {
-    ($this: ty) => {
-        impl Spanned for $this {
-            fn span(&self) -> Span {
-                span_with_attrs!(self)
-            }
-        }
-    };
-}
-
-// Implement `Spanned` for structs with `attrs` field.
-implement_spanned!(ast::Expr);
-implement_spanned!(ast::Field);
-implement_spanned!(ast::ForeignItem);
-implement_spanned!(ast::Item);
-implement_spanned!(ast::Local);
-implement_spanned!(ast::TraitItem);
-implement_spanned!(ast::ImplItem);
-
-impl Spanned for ast::Stmt {
-    fn span(&self) -> Span {
-        match self.node {
-            ast::StmtKind::Local(ref local) => mk_sp(local.span().lo(), self.span.hi()),
-            ast::StmtKind::Item(ref item) => mk_sp(item.span().lo(), self.span.hi()),
-            ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => {
-                mk_sp(expr.span().lo(), self.span.hi())
-            }
-            ast::StmtKind::Mac(ref mac) => {
-                let (_, _, ref attrs) = **mac;
-                if attrs.is_empty() {
-                    self.span
-                } else {
-                    mk_sp(attrs[0].span.lo(), self.span.hi())
-                }
-            }
-        }
-    }
-}
-
-impl Spanned for ast::Pat {
-    fn span(&self) -> Span {
-        self.span
-    }
-}
-
-impl Spanned for ast::Ty {
-    fn span(&self) -> Span {
-        self.span
-    }
-}
-
-impl Spanned for ast::Arm {
-    fn span(&self) -> Span {
-        span_with_attrs_lo_hi!(self, self.pats[0].span.lo(), self.body.span.hi())
-    }
-}
-
-impl Spanned for ast::Arg {
-    fn span(&self) -> Span {
-        if ::items::is_named_arg(self) {
-            mk_sp(self.pat.span.lo(), self.ty.span.hi())
-        } else {
-            self.ty.span
-        }
-    }
-}
-
-impl Spanned for ast::GenericParam {
-    fn span(&self) -> Span {
-        match *self {
-            ast::GenericParam::Lifetime(ref lifetime_def) => lifetime_def.span(),
-            ast::GenericParam::Type(ref ty) => ty.span(),
-        }
-    }
-}
-
-impl Spanned for ast::StructField {
-    fn span(&self) -> Span {
-        span_with_attrs_lo_hi!(self, self.span.lo(), self.ty.span.hi())
-    }
-}
-
-impl Spanned for ast::WherePredicate {
-    fn span(&self) -> Span {
-        match *self {
-            ast::WherePredicate::BoundPredicate(ref p) => p.span,
-            ast::WherePredicate::RegionPredicate(ref p) => p.span,
-            ast::WherePredicate::EqPredicate(ref p) => p.span,
-        }
-    }
-}
-
-impl Spanned for ast::FunctionRetTy {
-    fn span(&self) -> Span {
-        match *self {
-            ast::FunctionRetTy::Default(span) => span,
-            ast::FunctionRetTy::Ty(ref ty) => ty.span,
-        }
-    }
-}
-
-impl Spanned for ast::TyParam {
-    fn span(&self) -> Span {
-        // Note that ty.span is the span for ty.ident, not the whole item.
-        let lo = if self.attrs.is_empty() {
-            self.span.lo()
-        } else {
-            self.attrs[0].span.lo()
-        };
-        if let Some(ref def) = self.default {
-            return mk_sp(lo, def.span.hi());
-        }
-        if self.bounds.is_empty() {
-            return mk_sp(lo, self.span.hi());
-        }
-        let hi = self.bounds[self.bounds.len() - 1].span().hi();
-        mk_sp(lo, hi)
-    }
-}
-
-impl Spanned for ast::TyParamBound {
-    fn span(&self) -> Span {
-        match *self {
-            ast::TyParamBound::TraitTyParamBound(ref ptr, _) => ptr.span,
-            ast::TyParamBound::RegionTyParamBound(ref l) => l.span,
-        }
-    }
-}
-
-impl Spanned for ast::LifetimeDef {
-    fn span(&self) -> Span {
-        let hi = if self.bounds.is_empty() {
-            self.lifetime.span.hi()
-        } else {
-            self.bounds[self.bounds.len() - 1].span.hi()
-        };
-        mk_sp(self.lifetime.span.lo(), hi)
-    }
-}
-
-impl Spanned for MacroArg {
-    fn span(&self) -> Span {
-        match *self {
-            MacroArg::Expr(ref expr) => expr.span(),
-            MacroArg::Ty(ref ty) => ty.span(),
-            MacroArg::Pat(ref pat) => pat.span(),
-        }
-    }
-}
diff --git a/src/string.rs b/src/string.rs
deleted file mode 100644
index 2386d90ec8a..00000000000
--- a/src/string.rs
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Format string literals.
-
-use regex::Regex;
-use unicode_segmentation::UnicodeSegmentation;
-
-use config::Config;
-use shape::Shape;
-use utils::wrap_str;
-
-const MIN_STRING: usize = 10;
-
-pub struct StringFormat<'a> {
-    pub opener: &'a str,
-    pub closer: &'a str,
-    pub line_start: &'a str,
-    pub line_end: &'a str,
-    pub shape: Shape,
-    pub trim_end: bool,
-    pub config: &'a Config,
-}
-
-impl<'a> StringFormat<'a> {
-    pub fn new(shape: Shape, config: &'a Config) -> StringFormat<'a> {
-        StringFormat {
-            opener: "\"",
-            closer: "\"",
-            line_start: " ",
-            line_end: "\\",
-            shape,
-            trim_end: false,
-            config,
-        }
-    }
-}
-
-// FIXME: simplify this!
-pub fn rewrite_string<'a>(
-    orig: &str,
-    fmt: &StringFormat<'a>,
-    max_width: Option<usize>,
-) -> Option<String> {
-    // Strip line breaks.
-    let re = Regex::new(r"([^\\](\\\\)*)\\[\n\r][[:space:]]*").unwrap();
-    let stripped_str = re.replace_all(orig, "$1");
-
-    let graphemes = UnicodeSegmentation::graphemes(&*stripped_str, false).collect::<Vec<&str>>();
-    let shape = fmt.shape;
-    let indent = shape.indent.to_string(fmt.config);
-    let punctuation = ":,;.";
-
-    // `cur_start` is the position in `orig` of the start of the current line.
-    let mut cur_start = 0;
-    let mut result = String::with_capacity(
-        stripped_str
-            .len()
-            .checked_next_power_of_two()
-            .unwrap_or(usize::max_value()),
-    );
-    result.push_str(fmt.opener);
-
-    let ender_length = fmt.line_end.len();
-    // If we cannot put at least a single character per line, the rewrite won't
-    // succeed.
-    let mut max_chars = shape
-        .width
-        .checked_sub(fmt.opener.len() + ender_length + 1)? + 1;
-
-    // Snip a line at a time from `orig` until it is used up. Push the snippet
-    // onto result.
-    'outer: loop {
-        // `cur_end` will be where we break the line, as an offset into `orig`.
-        // Initialised to the maximum it could be (which may be beyond `orig`).
-        let mut cur_end = cur_start + max_chars;
-
-        // We can fit the rest of the string on this line, so we're done.
-        if cur_end >= graphemes.len() {
-            let line = &graphemes[cur_start..].join("");
-            result.push_str(line);
-            break 'outer;
-        }
-
-        // Push cur_end left until we reach whitespace (or the line is too small).
-        while !graphemes[cur_end - 1].trim().is_empty() {
-            cur_end -= 1;
-            if cur_end < cur_start + MIN_STRING {
-                // We couldn't find whitespace before the string got too small.
-                // So start again at the max length and look for punctuation.
-                cur_end = cur_start + max_chars;
-                while !punctuation.contains(graphemes[cur_end - 1]) {
-                    cur_end -= 1;
-
-                    // If we can't break at whitespace or punctuation, grow the string instead.
-                    if cur_end < cur_start + MIN_STRING {
-                        cur_end = cur_start + max_chars;
-                        while !(punctuation.contains(graphemes[cur_end - 1])
-                            || graphemes[cur_end - 1].trim().is_empty())
-                        {
-                            if cur_end >= graphemes.len() {
-                                let line = &graphemes[cur_start..].join("");
-                                result.push_str(line);
-                                break 'outer;
-                            }
-                            cur_end += 1;
-                        }
-                        break;
-                    }
-                }
-                break;
-            }
-        }
-        // Make sure there is no whitespace to the right of the break.
-        while cur_end < stripped_str.len() && graphemes[cur_end].trim().is_empty() {
-            cur_end += 1;
-        }
-
-        // Make the current line and add it on to result.
-        let raw_line = graphemes[cur_start..cur_end].join("");
-        let line = if fmt.trim_end {
-            raw_line.trim()
-        } else {
-            raw_line.as_str()
-        };
-
-        result.push_str(line);
-        result.push_str(fmt.line_end);
-        result.push('\n');
-        result.push_str(&indent);
-        result.push_str(fmt.line_start);
-
-        // The next line starts where the current line ends.
-        cur_start = cur_end;
-
-        if let Some(new_max_chars) = max_width {
-            max_chars = new_max_chars.checked_sub(fmt.opener.len() + ender_length + 1)? + 1;
-        }
-    }
-
-    result.push_str(fmt.closer);
-    wrap_str(result, fmt.config.max_width(), fmt.shape)
-}
-
-#[cfg(test)]
-mod test {
-    use super::{rewrite_string, StringFormat};
-    use shape::{Indent, Shape};
-
-    #[test]
-    fn issue343() {
-        let config = Default::default();
-        let fmt = StringFormat::new(Shape::legacy(2, Indent::empty()), &config);
-        rewrite_string("eq_", &fmt, None);
-    }
-}
diff --git a/src/types.rs b/src/types.rs
deleted file mode 100644
index a7472567a81..00000000000
--- a/src/types.rs
+++ /dev/null
@@ -1,820 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::iter::ExactSizeIterator;
-use std::ops::Deref;
-
-use syntax::ast::{self, FunctionRetTy, Mutability};
-use syntax::codemap::{self, BytePos, Span};
-use syntax::print::pprust;
-use syntax::symbol::keywords;
-
-use codemap::SpanUtils;
-use config::{IndentStyle, TypeDensity};
-use expr::{rewrite_pair, rewrite_tuple, rewrite_unary_prefix, wrap_args_with_parens, PairParts};
-use items::{format_generics_item_list, generics_shape_from_config};
-use lists::{definitive_tactic, itemize_list, write_list, ListFormatting, ListTactic, Separator,
-            SeparatorPlace, SeparatorTactic};
-use macros::{rewrite_macro, MacroPosition};
-use rewrite::{Rewrite, RewriteContext};
-use shape::Shape;
-use spanned::Spanned;
-use utils::{colon_spaces, extra_offset, first_line_width, format_abi, format_mutability,
-            last_line_width, mk_sp};
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-pub enum PathContext {
-    Expr,
-    Type,
-    Import,
-}
-
-// Does not wrap on simple segments.
-pub fn rewrite_path(
-    context: &RewriteContext,
-    path_context: PathContext,
-    qself: Option<&ast::QSelf>,
-    path: &ast::Path,
-    shape: Shape,
-) -> Option<String> {
-    let skip_count = qself.map_or(0, |x| x.position);
-
-    let mut result = if path.is_global() && qself.is_none() && path_context != PathContext::Import {
-        "::".to_owned()
-    } else {
-        String::new()
-    };
-
-    let mut span_lo = path.span.lo();
-
-    if let Some(qself) = qself {
-        result.push('<');
-        if context.config.spaces_within_parens_and_brackets() {
-            result.push_str(" ")
-        }
-
-        let fmt_ty = qself.ty.rewrite(context, shape)?;
-        result.push_str(&fmt_ty);
-
-        if skip_count > 0 {
-            result.push_str(" as ");
-            if path.is_global() && path_context != PathContext::Import {
-                result.push_str("::");
-            }
-
-            // 3 = ">::".len()
-            let shape = shape.sub_width(3)?;
-
-            result = rewrite_path_segments(
-                PathContext::Type,
-                result,
-                path.segments.iter().take(skip_count),
-                span_lo,
-                path.span.hi(),
-                context,
-                shape,
-            )?;
-        }
-
-        if context.config.spaces_within_parens_and_brackets() {
-            result.push_str(" ")
-        }
-
-        result.push_str(">::");
-        span_lo = qself.ty.span.hi() + BytePos(1);
-    }
-
-    rewrite_path_segments(
-        path_context,
-        result,
-        path.segments.iter().skip(skip_count),
-        span_lo,
-        path.span.hi(),
-        context,
-        shape,
-    )
-}
-
-fn rewrite_path_segments<'a, I>(
-    path_context: PathContext,
-    mut buffer: String,
-    iter: I,
-    mut span_lo: BytePos,
-    span_hi: BytePos,
-    context: &RewriteContext,
-    shape: Shape,
-) -> Option<String>
-where
-    I: Iterator<Item = &'a ast::PathSegment>,
-{
-    let mut first = true;
-    let shape = shape.visual_indent(0);
-
-    for segment in iter {
-        // Indicates a global path, shouldn't be rendered.
-        if segment.identifier.name == keywords::CrateRoot.name() {
-            continue;
-        }
-        if first {
-            first = false;
-        } else {
-            buffer.push_str("::");
-        }
-
-        let extra_offset = extra_offset(&buffer, shape);
-        let new_shape = shape.shrink_left(extra_offset)?;
-        let segment_string = rewrite_segment(
-            path_context,
-            segment,
-            &mut span_lo,
-            span_hi,
-            context,
-            new_shape,
-        )?;
-
-        buffer.push_str(&segment_string);
-    }
-
-    Some(buffer)
-}
-
-#[derive(Debug)]
-enum SegmentParam<'a> {
-    LifeTime(&'a ast::Lifetime),
-    Type(&'a ast::Ty),
-    Binding(&'a ast::TypeBinding),
-}
-
-impl<'a> SegmentParam<'a> {
-    fn get_span(&self) -> Span {
-        match *self {
-            SegmentParam::LifeTime(lt) => lt.span,
-            SegmentParam::Type(ty) => ty.span,
-            SegmentParam::Binding(binding) => binding.span,
-        }
-    }
-}
-
-impl<'a> Rewrite for SegmentParam<'a> {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        match *self {
-            SegmentParam::LifeTime(lt) => lt.rewrite(context, shape),
-            SegmentParam::Type(ty) => ty.rewrite(context, shape),
-            SegmentParam::Binding(binding) => {
-                let mut result = match context.config.type_punctuation_density() {
-                    TypeDensity::Wide => format!("{} = ", binding.ident),
-                    TypeDensity::Compressed => format!("{}=", binding.ident),
-                };
-                let budget = shape.width.checked_sub(result.len())?;
-                let rewrite = binding
-                    .ty
-                    .rewrite(context, Shape::legacy(budget, shape.indent + result.len()))?;
-                result.push_str(&rewrite);
-                Some(result)
-            }
-        }
-    }
-}
-
-// Formats a path segment. There are some hacks involved to correctly determine
-// the segment's associated span since it's not part of the AST.
-//
-// The span_lo is assumed to be greater than the end of any previous segment's
-// parameters and lesser or equal than the start of current segment.
-//
-// span_hi is assumed equal to the end of the entire path.
-//
-// When the segment contains a positive number of parameters, we update span_lo
-// so that invariants described above will hold for the next segment.
-fn rewrite_segment(
-    path_context: PathContext,
-    segment: &ast::PathSegment,
-    span_lo: &mut BytePos,
-    span_hi: BytePos,
-    context: &RewriteContext,
-    shape: Shape,
-) -> Option<String> {
-    let ident_len = segment.identifier.to_string().len();
-    let shape = shape.shrink_left(ident_len)?;
-
-    let params = if let Some(ref params) = segment.parameters {
-        match **params {
-            ast::PathParameters::AngleBracketed(ref data)
-                if !data.lifetimes.is_empty() || !data.types.is_empty()
-                    || !data.bindings.is_empty() =>
-            {
-                let param_list = data.lifetimes
-                    .iter()
-                    .map(SegmentParam::LifeTime)
-                    .chain(data.types.iter().map(|x| SegmentParam::Type(&*x)))
-                    .chain(data.bindings.iter().map(|x| SegmentParam::Binding(&*x)))
-                    .collect::<Vec<_>>();
-
-                let next_span_lo = param_list.last().unwrap().get_span().hi() + BytePos(1);
-                let list_lo = context.codemap.span_after(mk_sp(*span_lo, span_hi), "<");
-                let separator = if path_context == PathContext::Expr {
-                    "::"
-                } else {
-                    ""
-                };
-
-                let generics_shape =
-                    generics_shape_from_config(context.config, shape, separator.len())?;
-                let one_line_width = shape.width.checked_sub(separator.len() + 2)?;
-                let items = itemize_list(
-                    context.codemap,
-                    param_list.into_iter(),
-                    ">",
-                    ",",
-                    |param| param.get_span().lo(),
-                    |param| param.get_span().hi(),
-                    |seg| seg.rewrite(context, generics_shape),
-                    list_lo,
-                    span_hi,
-                    false,
-                );
-                let generics_str =
-                    format_generics_item_list(context, items, generics_shape, one_line_width)?;
-
-                // Update position of last bracket.
-                *span_lo = next_span_lo;
-
-                format!("{}{}", separator, generics_str)
-            }
-            ast::PathParameters::Parenthesized(ref data) => {
-                let output = match data.output {
-                    Some(ref ty) => FunctionRetTy::Ty(ty.clone()),
-                    None => FunctionRetTy::Default(codemap::DUMMY_SP),
-                };
-                format_function_type(
-                    data.inputs.iter().map(|x| &**x),
-                    &output,
-                    false,
-                    data.span,
-                    context,
-                    shape,
-                )?
-            }
-            _ => String::new(),
-        }
-    } else {
-        String::new()
-    };
-
-    Some(format!("{}{}", segment.identifier, params))
-}
-
-fn format_function_type<'a, I>(
-    inputs: I,
-    output: &FunctionRetTy,
-    variadic: bool,
-    span: Span,
-    context: &RewriteContext,
-    shape: Shape,
-) -> Option<String>
-where
-    I: ExactSizeIterator,
-    <I as Iterator>::Item: Deref,
-    <I::Item as 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<T>
-    where
-        T: Deref,
-        <T as Deref>::Target: Rewrite + Spanned,
-    {
-        Regular(Box<T>),
-        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 = shape.width.checked_sub(2)?;
-    // 1 for (
-    let offset = match context.config.indent_style() {
-        IndentStyle::Block => {
-            shape
-                .block()
-                .block_indent(context.config.tab_spaces())
-                .indent
-        }
-        IndentStyle::Visual => shape.indent + 1,
-    };
-    let list_shape = Shape::legacy(budget, offset);
-    let list_lo = context.codemap.span_after(span, "(");
-    let items = itemize_list(
-        context.codemap,
-        // 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),
-        ")",
-        ",",
-        |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, list_shape),
-            ArgumentKind::Variadic(_) => Some("...".to_owned()),
-        },
-        list_lo,
-        span.hi(),
-        false,
-    );
-
-    let item_vec: Vec<_> = items.collect();
-
-    let tactic = definitive_tactic(
-        &*item_vec,
-        ListTactic::HorizontalVertical,
-        Separator::Comma,
-        budget,
-    );
-
-    let fmt = ListFormatting {
-        tactic,
-        separator: ",",
-        trailing_separator: if !context.use_block_indent() || variadic {
-            SeparatorTactic::Never
-        } else {
-            context.config.trailing_comma()
-        },
-        separator_place: SeparatorPlace::Back,
-        shape: list_shape,
-        ends_with_newline: tactic.ends_with_newline(context.config.indent_style()),
-        preserve_newline: true,
-        config: context.config,
-    };
-
-    let list_str = write_list(&item_vec, &fmt)?;
-
-    let ty_shape = match context.config.indent_style() {
-        // 4 = " -> "
-        IndentStyle::Block => shape.offset_left(4)?,
-        IndentStyle::Visual => shape.block_left(4)?,
-    };
-    let output = match *output {
-        FunctionRetTy::Ty(ref ty) => {
-            let type_str = ty.rewrite(context, ty_shape)?;
-            format!(" -> {}", type_str)
-        }
-        FunctionRetTy::Default(..) => String::new(),
-    };
-
-    let extendable = (!list_str.contains('\n') || list_str.is_empty()) && !output.contains('\n');
-    let args = wrap_args_with_parens(
-        context,
-        &list_str,
-        extendable,
-        shape.sub_width(first_line_width(&output))?,
-        Shape::indented(offset, context.config),
-    );
-    if last_line_width(&args) + first_line_width(&output) <= shape.width {
-        Some(format!("{}{}", args, output))
-    } else {
-        Some(format!(
-            "{}\n{}{}",
-            args,
-            offset.to_string(context.config),
-            output.trim_left()
-        ))
-    }
-}
-
-fn type_bound_colon(context: &RewriteContext) -> &'static str {
-    colon_spaces(
-        context.config.space_before_colon(),
-        context.config.space_after_colon(),
-    )
-}
-
-impl Rewrite for ast::WherePredicate {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        // TODO: dead spans?
-        let result = match *self {
-            ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
-                ref bound_generic_params,
-                ref bounded_ty,
-                ref bounds,
-                ..
-            }) => {
-                let type_str = bounded_ty.rewrite(context, shape)?;
-
-                let colon = type_bound_colon(context);
-
-                if let Some(lifetime_str) =
-                    rewrite_lifetime_param(context, shape, bound_generic_params)
-                {
-                    // 6 = "for<> ".len()
-                    let used_width = lifetime_str.len() + type_str.len() + colon.len() + 6;
-                    let ty_shape = shape.offset_left(used_width)?;
-                    let bounds = bounds
-                        .iter()
-                        .map(|ty_bound| ty_bound.rewrite(context, ty_shape))
-                        .collect::<Option<Vec<_>>>()?;
-                    let bounds_str = join_bounds(context, ty_shape, &bounds);
-
-                    if context.config.spaces_within_parens_and_brackets()
-                        && !lifetime_str.is_empty()
-                    {
-                        format!(
-                            "for< {} > {}{}{}",
-                            lifetime_str, type_str, colon, bounds_str
-                        )
-                    } else {
-                        format!("for<{}> {}{}{}", lifetime_str, type_str, colon, bounds_str)
-                    }
-                } else {
-                    let used_width = type_str.len() + colon.len();
-                    let ty_shape = match context.config.indent_style() {
-                        IndentStyle::Visual => shape.block_left(used_width)?,
-                        IndentStyle::Block => shape,
-                    };
-                    let bounds = bounds
-                        .iter()
-                        .map(|ty_bound| ty_bound.rewrite(context, ty_shape))
-                        .collect::<Option<Vec<_>>>()?;
-                    let overhead = type_str.len() + colon.len();
-                    let bounds_str = join_bounds(context, ty_shape.sub_width(overhead)?, &bounds);
-
-                    format!("{}{}{}", type_str, colon, bounds_str)
-                }
-            }
-            ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
-                ref lifetime,
-                ref bounds,
-                ..
-            }) => rewrite_bounded_lifetime(lifetime, bounds.iter(), context, shape)?,
-            ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
-                ref lhs_ty,
-                ref rhs_ty,
-                ..
-            }) => {
-                let lhs_ty_str = lhs_ty.rewrite(context, shape)?;
-                // 3 = " = ".len()
-                let used_width = 3 + lhs_ty_str.len();
-                let budget = shape.width.checked_sub(used_width)?;
-                let rhs_ty_str =
-                    rhs_ty.rewrite(context, Shape::legacy(budget, shape.indent + used_width))?;
-                format!("{} = {}", lhs_ty_str, rhs_ty_str)
-            }
-        };
-
-        Some(result)
-    }
-}
-
-impl Rewrite for ast::LifetimeDef {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        rewrite_bounded_lifetime(&self.lifetime, self.bounds.iter(), context, shape)
-    }
-}
-
-fn rewrite_bounded_lifetime<'b, I>(
-    lt: &ast::Lifetime,
-    bounds: I,
-    context: &RewriteContext,
-    shape: Shape,
-) -> Option<String>
-where
-    I: ExactSizeIterator<Item = &'b ast::Lifetime>,
-{
-    let result = lt.rewrite(context, shape)?;
-
-    if bounds.len() == 0 {
-        Some(result)
-    } else {
-        let appendix = bounds
-            .into_iter()
-            .map(|b| b.rewrite(context, shape))
-            .collect::<Option<Vec<_>>>()?;
-        let colon = type_bound_colon(context);
-        let overhead = last_line_width(&result) + colon.len();
-        let result = format!(
-            "{}{}{}",
-            result,
-            colon,
-            join_bounds(context, shape.sub_width(overhead)?, &appendix)
-        );
-        Some(result)
-    }
-}
-
-impl Rewrite for ast::TyParamBound {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        match *self {
-            ast::TyParamBound::TraitTyParamBound(ref tref, ast::TraitBoundModifier::None) => {
-                tref.rewrite(context, shape)
-            }
-            ast::TyParamBound::TraitTyParamBound(ref tref, ast::TraitBoundModifier::Maybe) => {
-                Some(format!(
-                    "?{}",
-                    tref.rewrite(context, shape.offset_left(1)?)?
-                ))
-            }
-            ast::TyParamBound::RegionTyParamBound(ref l) => l.rewrite(context, shape),
-        }
-    }
-}
-
-impl Rewrite for ast::Lifetime {
-    fn rewrite(&self, _: &RewriteContext, _: Shape) -> Option<String> {
-        Some(pprust::lifetime_to_string(self))
-    }
-}
-
-impl Rewrite for ast::TyParamBounds {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        let strs = self.iter()
-            .map(|b| b.rewrite(context, shape))
-            .collect::<Option<Vec<_>>>()?;
-        Some(join_bounds(context, shape, &strs))
-    }
-}
-
-impl Rewrite for ast::TyParam {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        let mut result = String::with_capacity(128);
-        // FIXME: If there are more than one attributes, this will force multiline.
-        match self.attrs.rewrite(context, shape) {
-            Some(ref rw) if !rw.is_empty() => result.push_str(&format!("{} ", rw)),
-            _ => (),
-        }
-        result.push_str(&self.ident.to_string());
-        if !self.bounds.is_empty() {
-            result.push_str(type_bound_colon(context));
-            let strs = self.bounds
-                .iter()
-                .map(|ty_bound| ty_bound.rewrite(context, shape))
-                .collect::<Option<Vec<_>>>()?;
-            result.push_str(&join_bounds(context, shape, &strs));
-        }
-        if let Some(ref def) = self.default {
-            let eq_str = match context.config.type_punctuation_density() {
-                TypeDensity::Compressed => "=",
-                TypeDensity::Wide => " = ",
-            };
-            result.push_str(eq_str);
-            let budget = shape.width.checked_sub(result.len())?;
-            let rewrite = def.rewrite(context, Shape::legacy(budget, shape.indent + result.len()))?;
-            result.push_str(&rewrite);
-        }
-
-        Some(result)
-    }
-}
-
-impl Rewrite for ast::PolyTraitRef {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        if let Some(lifetime_str) =
-            rewrite_lifetime_param(context, shape, &self.bound_generic_params)
-        {
-            // 6 is "for<> ".len()
-            let extra_offset = lifetime_str.len() + 6;
-            let path_str = self.trait_ref
-                .rewrite(context, shape.offset_left(extra_offset)?)?;
-
-            Some(
-                if context.config.spaces_within_parens_and_brackets() && !lifetime_str.is_empty() {
-                    format!("for< {} > {}", lifetime_str, path_str)
-                } else {
-                    format!("for<{}> {}", lifetime_str, path_str)
-                },
-            )
-        } else {
-            self.trait_ref.rewrite(context, shape)
-        }
-    }
-}
-
-impl Rewrite for ast::TraitRef {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        rewrite_path(context, PathContext::Type, None, &self.path, shape)
-    }
-}
-
-impl Rewrite for ast::Ty {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        match self.node {
-            ast::TyKind::TraitObject(ref bounds, ..) => bounds.rewrite(context, shape),
-            ast::TyKind::Ptr(ref mt) => {
-                let prefix = match mt.mutbl {
-                    Mutability::Mutable => "*mut ",
-                    Mutability::Immutable => "*const ",
-                };
-
-                rewrite_unary_prefix(context, prefix, &*mt.ty, shape)
-            }
-            ast::TyKind::Rptr(ref lifetime, ref mt) => {
-                let mut_str = format_mutability(mt.mutbl);
-                let mut_len = mut_str.len();
-                Some(match *lifetime {
-                    Some(ref lifetime) => {
-                        let lt_budget = shape.width.checked_sub(2 + mut_len)?;
-                        let lt_str = lifetime.rewrite(
-                            context,
-                            Shape::legacy(lt_budget, shape.indent + 2 + mut_len),
-                        )?;
-                        let lt_len = lt_str.len();
-                        let budget = shape.width.checked_sub(2 + mut_len + lt_len)?;
-                        format!(
-                            "&{} {}{}",
-                            lt_str,
-                            mut_str,
-                            mt.ty.rewrite(
-                                context,
-                                Shape::legacy(budget, shape.indent + 2 + mut_len + lt_len)
-                            )?
-                        )
-                    }
-                    None => {
-                        let budget = shape.width.checked_sub(1 + mut_len)?;
-                        format!(
-                            "&{}{}",
-                            mut_str,
-                            mt.ty.rewrite(
-                                context,
-                                Shape::legacy(budget, shape.indent + 1 + mut_len)
-                            )?
-                        )
-                    }
-                })
-            }
-            // FIXME: we drop any comments here, even though it's a silly place to put
-            // comments.
-            ast::TyKind::Paren(ref ty) => {
-                let budget = shape.width.checked_sub(2)?;
-                ty.rewrite(context, Shape::legacy(budget, shape.indent + 1))
-                    .map(|ty_str| {
-                        if context.config.spaces_within_parens_and_brackets() {
-                            format!("( {} )", ty_str)
-                        } else {
-                            format!("({})", ty_str)
-                        }
-                    })
-            }
-            ast::TyKind::Slice(ref ty) => {
-                let budget = if context.config.spaces_within_parens_and_brackets() {
-                    shape.width.checked_sub(4)?
-                } else {
-                    shape.width.checked_sub(2)?
-                };
-                ty.rewrite(context, Shape::legacy(budget, shape.indent + 1))
-                    .map(|ty_str| {
-                        if context.config.spaces_within_parens_and_brackets() {
-                            format!("[ {} ]", ty_str)
-                        } else {
-                            format!("[{}]", ty_str)
-                        }
-                    })
-            }
-            ast::TyKind::Tup(ref items) => rewrite_tuple(
-                context,
-                &::utils::ptr_vec_to_ref_vec(items),
-                self.span,
-                shape,
-            ),
-            ast::TyKind::Path(ref q_self, ref path) => {
-                rewrite_path(context, PathContext::Type, q_self.as_ref(), path, shape)
-            }
-            ast::TyKind::Array(ref ty, ref repeats) => {
-                let use_spaces = context.config.spaces_within_parens_and_brackets();
-                let lbr = if use_spaces { "[ " } else { "[" };
-                let rbr = if use_spaces { " ]" } else { "]" };
-                rewrite_pair(
-                    &**ty,
-                    &**repeats,
-                    PairParts::new(lbr, "; ", rbr),
-                    context,
-                    shape,
-                    SeparatorPlace::Back,
-                )
-            }
-            ast::TyKind::Infer => {
-                if shape.width >= 1 {
-                    Some("_".to_owned())
-                } else {
-                    None
-                }
-            }
-            ast::TyKind::BareFn(ref bare_fn) => rewrite_bare_fn(bare_fn, self.span, context, shape),
-            ast::TyKind::Never => Some(String::from("!")),
-            ast::TyKind::Mac(ref mac) => {
-                rewrite_macro(mac, None, context, shape, MacroPosition::Expression)
-            }
-            ast::TyKind::ImplicitSelf => Some(String::from("")),
-            ast::TyKind::ImplTrait(ref it) => it.rewrite(context, shape)
-                .map(|it_str| format!("impl {}", it_str)),
-            ast::TyKind::Err | ast::TyKind::Typeof(..) => unreachable!(),
-        }
-    }
-}
-
-fn rewrite_bare_fn(
-    bare_fn: &ast::BareFnTy,
-    span: Span,
-    context: &RewriteContext,
-    shape: Shape,
-) -> Option<String> {
-    let mut result = String::with_capacity(128);
-
-    if let Some(ref lifetime_str) = rewrite_lifetime_param(context, shape, &bare_fn.generic_params)
-    {
-        result.push_str("for<");
-        // 6 = "for<> ".len(), 4 = "for<".
-        // This doesn't work out so nicely for mutliline situation with lots of
-        // rightward drift. If that is a problem, we could use the list stuff.
-        result.push_str(lifetime_str);
-        result.push_str("> ");
-    }
-
-    result.push_str(::utils::format_unsafety(bare_fn.unsafety));
-
-    result.push_str(&format_abi(
-        bare_fn.abi,
-        context.config.force_explicit_abi(),
-        false,
-    ));
-
-    result.push_str("fn");
-
-    let func_ty_shape = shape.offset_left(result.len())?;
-
-    let rewrite = format_function_type(
-        bare_fn.decl.inputs.iter(),
-        &bare_fn.decl.output,
-        bare_fn.decl.variadic,
-        span,
-        context,
-        func_ty_shape,
-    )?;
-
-    result.push_str(&rewrite);
-
-    Some(result)
-}
-
-pub fn join_bounds(context: &RewriteContext, shape: Shape, type_strs: &[String]) -> String {
-    // Try to join types in a single line
-    let joiner = match context.config.type_punctuation_density() {
-        TypeDensity::Compressed => "+",
-        TypeDensity::Wide => " + ",
-    };
-    let result = type_strs.join(joiner);
-    if result.contains('\n') || result.len() > shape.width {
-        let joiner_indent = shape.indent.block_indent(context.config);
-        let joiner = format!("\n{}+ ", joiner_indent.to_string(context.config));
-        type_strs.join(&joiner)
-    } else {
-        result
-    }
-}
-
-pub fn can_be_overflowed_type(context: &RewriteContext, ty: &ast::Ty, len: usize) -> bool {
-    match ty.node {
-        ast::TyKind::Path(..) | ast::TyKind::Tup(..) => context.use_block_indent() && len == 1,
-        ast::TyKind::Rptr(_, ref mutty) | ast::TyKind::Ptr(ref mutty) => {
-            can_be_overflowed_type(context, &*mutty.ty, len)
-        }
-        _ => false,
-    }
-}
-
-/// Returns `None` if there is no `LifetimeDef` in the given generic parameters.
-fn rewrite_lifetime_param(
-    context: &RewriteContext,
-    shape: Shape,
-    generic_params: &[ast::GenericParam],
-) -> Option<String> {
-    let result = generic_params
-        .iter()
-        .filter(|p| p.is_lifetime_param())
-        .map(|lt| lt.rewrite(context, shape))
-        .collect::<Option<Vec<_>>>()?
-        .join(", ");
-    if result.is_empty() {
-        None
-    } else {
-        Some(result)
-    }
-}
diff --git a/src/utils.rs b/src/utils.rs
deleted file mode 100644
index 20f4fdfe6d0..00000000000
--- a/src/utils.rs
+++ /dev/null
@@ -1,480 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::borrow::Cow;
-
-use syntax::{abi, ptr};
-use syntax::ast::{self, Attribute, CrateSugar, MetaItem, MetaItemKind, NestedMetaItem,
-                  NestedMetaItemKind, Path, Visibility};
-use syntax::codemap::{BytePos, Span, NO_EXPANSION};
-
-use config::Color;
-use rewrite::RewriteContext;
-use shape::Shape;
-
-// When we get scoped annotations, we should have rustfmt::skip.
-const SKIP_ANNOTATION: &str = "rustfmt_skip";
-
-// Computes the length of a string's last line, minus offset.
-pub fn extra_offset(text: &str, shape: Shape) -> usize {
-    match text.rfind('\n') {
-        // 1 for newline character
-        Some(idx) => text.len()
-            .checked_sub(idx + 1 + shape.used_width())
-            .unwrap_or(0),
-        None => text.len(),
-    }
-}
-
-// Uses Cow to avoid allocating in the common cases.
-pub fn format_visibility(vis: &Visibility) -> Cow<'static, str> {
-    match *vis {
-        Visibility::Public => Cow::from("pub "),
-        Visibility::Inherited => Cow::from(""),
-        Visibility::Crate(_, CrateSugar::PubCrate) => Cow::from("pub(crate) "),
-        Visibility::Crate(_, CrateSugar::JustCrate) => Cow::from("crate "),
-        Visibility::Restricted { ref path, .. } => {
-            let Path { ref segments, .. } = **path;
-            let mut segments_iter = segments.iter().map(|seg| seg.identifier.name.to_string());
-            if path.is_global() {
-                segments_iter
-                    .next()
-                    .expect("Non-global path in pub(restricted)?");
-            }
-            let is_keyword = |s: &str| s == "self" || s == "super";
-            let path = segments_iter.collect::<Vec<_>>().join("::");
-            let in_str = if is_keyword(&path) { "" } else { "in " };
-
-            Cow::from(format!("pub({}{}) ", in_str, path))
-        }
-    }
-}
-
-#[inline]
-pub fn format_constness(constness: ast::Constness) -> &'static str {
-    match constness {
-        ast::Constness::Const => "const ",
-        ast::Constness::NotConst => "",
-    }
-}
-
-#[inline]
-pub fn format_defaultness(defaultness: ast::Defaultness) -> &'static str {
-    match defaultness {
-        ast::Defaultness::Default => "default ",
-        ast::Defaultness::Final => "",
-    }
-}
-
-#[inline]
-pub fn format_unsafety(unsafety: ast::Unsafety) -> &'static str {
-    match unsafety {
-        ast::Unsafety::Unsafe => "unsafe ",
-        ast::Unsafety::Normal => "",
-    }
-}
-
-#[inline]
-pub fn format_mutability(mutability: ast::Mutability) -> &'static str {
-    match mutability {
-        ast::Mutability::Mutable => "mut ",
-        ast::Mutability::Immutable => "",
-    }
-}
-
-#[inline]
-pub fn format_abi(abi: abi::Abi, explicit_abi: bool, is_mod: bool) -> Cow<'static, str> {
-    if abi == abi::Abi::Rust && !is_mod {
-        Cow::from("")
-    } else if abi == abi::Abi::C && !explicit_abi {
-        Cow::from("extern ")
-    } else {
-        Cow::from(format!("extern {} ", abi))
-    }
-}
-
-#[inline]
-// Transform `Vec<syntax::ptr::P<T>>` into `Vec<&T>`
-pub fn ptr_vec_to_ref_vec<T>(vec: &[ptr::P<T>]) -> Vec<&T> {
-    vec.iter().map(|x| &**x).collect::<Vec<_>>()
-}
-
-#[inline]
-pub fn filter_attributes(attrs: &[ast::Attribute], style: ast::AttrStyle) -> Vec<ast::Attribute> {
-    attrs
-        .iter()
-        .filter(|a| a.style == style)
-        .cloned()
-        .collect::<Vec<_>>()
-}
-
-#[inline]
-pub fn inner_attributes(attrs: &[ast::Attribute]) -> Vec<ast::Attribute> {
-    filter_attributes(attrs, ast::AttrStyle::Inner)
-}
-
-#[inline]
-pub fn outer_attributes(attrs: &[ast::Attribute]) -> Vec<ast::Attribute> {
-    filter_attributes(attrs, ast::AttrStyle::Outer)
-}
-
-#[inline]
-pub fn last_line_contains_single_line_comment(s: &str) -> bool {
-    s.lines().last().map_or(false, |l| l.contains("//"))
-}
-
-#[inline]
-pub fn is_attributes_extendable(attrs_str: &str) -> bool {
-    !attrs_str.contains('\n') && !last_line_contains_single_line_comment(attrs_str)
-}
-
-// The width of the first line in s.
-#[inline]
-pub fn first_line_width(s: &str) -> usize {
-    match s.find('\n') {
-        Some(n) => n,
-        None => s.len(),
-    }
-}
-
-// The width of the last line in s.
-#[inline]
-pub fn last_line_width(s: &str) -> usize {
-    match s.rfind('\n') {
-        Some(n) => s.len() - n - 1,
-        None => s.len(),
-    }
-}
-
-// The total used width of the last line.
-#[inline]
-pub fn last_line_used_width(s: &str, offset: usize) -> usize {
-    if s.contains('\n') {
-        last_line_width(s)
-    } else {
-        offset + s.len()
-    }
-}
-
-#[inline]
-pub fn trimmed_last_line_width(s: &str) -> usize {
-    match s.rfind('\n') {
-        Some(n) => s[(n + 1)..].trim().len(),
-        None => s.trim().len(),
-    }
-}
-
-#[inline]
-pub fn last_line_extendable(s: &str) -> bool {
-    if s.ends_with("\"#") {
-        return true;
-    }
-    for c in s.chars().rev() {
-        match c {
-            '(' | ')' | ']' | '}' | '?' | '>' => continue,
-            '\n' => break,
-            _ if c.is_whitespace() => continue,
-            _ => return false,
-        }
-    }
-    true
-}
-
-#[inline]
-fn is_skip(meta_item: &MetaItem) -> bool {
-    match meta_item.node {
-        MetaItemKind::Word => meta_item.name == SKIP_ANNOTATION,
-        MetaItemKind::List(ref l) => {
-            meta_item.name == "cfg_attr" && l.len() == 2 && is_skip_nested(&l[1])
-        }
-        _ => false,
-    }
-}
-
-#[inline]
-fn is_skip_nested(meta_item: &NestedMetaItem) -> bool {
-    match meta_item.node {
-        NestedMetaItemKind::MetaItem(ref mi) => is_skip(mi),
-        NestedMetaItemKind::Literal(_) => false,
-    }
-}
-
-#[inline]
-pub fn contains_skip(attrs: &[Attribute]) -> bool {
-    attrs
-        .iter()
-        .any(|a| a.meta().map_or(false, |a| is_skip(&a)))
-}
-
-#[inline]
-pub fn semicolon_for_expr(context: &RewriteContext, expr: &ast::Expr) -> bool {
-    match expr.node {
-        ast::ExprKind::Ret(..) | ast::ExprKind::Continue(..) | ast::ExprKind::Break(..) => {
-            context.config.trailing_semicolon()
-        }
-        _ => false,
-    }
-}
-
-#[inline]
-pub fn semicolon_for_stmt(context: &RewriteContext, stmt: &ast::Stmt) -> bool {
-    match stmt.node {
-        ast::StmtKind::Semi(ref expr) => match expr.node {
-            ast::ExprKind::While(..)
-            | ast::ExprKind::WhileLet(..)
-            | ast::ExprKind::Loop(..)
-            | ast::ExprKind::ForLoop(..) => false,
-            ast::ExprKind::Break(..) | ast::ExprKind::Continue(..) | ast::ExprKind::Ret(..) => {
-                context.config.trailing_semicolon()
-            }
-            _ => true,
-        },
-        ast::StmtKind::Expr(..) => false,
-        _ => true,
-    }
-}
-
-#[inline]
-pub fn stmt_expr(stmt: &ast::Stmt) -> Option<&ast::Expr> {
-    match stmt.node {
-        ast::StmtKind::Expr(ref expr) => Some(expr),
-        _ => None,
-    }
-}
-
-#[inline]
-pub fn count_newlines(input: &str) -> usize {
-    input.chars().filter(|&c| c == '\n').count()
-}
-
-// Macro for deriving implementations of Serialize/Deserialize for enums
-#[macro_export]
-macro_rules! impl_enum_serialize_and_deserialize {
-    ( $e:ident, $( $x:ident ),* ) => {
-        impl ::serde::ser::Serialize for $e {
-            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-                where S: ::serde::ser::Serializer
-            {
-                use serde::ser::Error;
-
-                // We don't know whether the user of the macro has given us all options.
-                #[allow(unreachable_patterns)]
-                match *self {
-                    $(
-                        $e::$x => serializer.serialize_str(stringify!($x)),
-                    )*
-                    _ => {
-                        Err(S::Error::custom(format!("Cannot serialize {:?}", self)))
-                    }
-                }
-            }
-        }
-
-        impl<'de> ::serde::de::Deserialize<'de> for $e {
-            fn deserialize<D>(d: D) -> Result<Self, D::Error>
-                    where D: ::serde::Deserializer<'de> {
-                use serde::de::{Error, Visitor};
-                use std::marker::PhantomData;
-                use std::fmt;
-                struct StringOnly<T>(PhantomData<T>);
-                impl<'de, T> Visitor<'de> for StringOnly<T>
-                        where T: ::serde::Deserializer<'de> {
-                    type Value = String;
-                    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-                        formatter.write_str("string")
-                    }
-                    fn visit_str<E>(self, value: &str) -> Result<String, E> {
-                        Ok(String::from(value))
-                    }
-                }
-                let s = d.deserialize_string(StringOnly::<D>(PhantomData))?;
-                $(
-                    if stringify!($x).eq_ignore_ascii_case(&s) {
-                      return Ok($e::$x);
-                    }
-                )*
-                static ALLOWED: &'static[&str] = &[$(stringify!($x),)*];
-                Err(D::Error::unknown_variant(&s, ALLOWED))
-            }
-        }
-
-        impl ::std::str::FromStr for $e {
-            type Err = &'static str;
-
-            fn from_str(s: &str) -> Result<Self, Self::Err> {
-                $(
-                    if stringify!($x).eq_ignore_ascii_case(s) {
-                        return Ok($e::$x);
-                    }
-                )*
-                Err("Bad variant")
-            }
-        }
-
-        impl ::config::ConfigType for $e {
-            fn doc_hint() -> String {
-                let mut variants = Vec::new();
-                $(
-                    variants.push(stringify!($x));
-                )*
-                format!("[{}]", variants.join("|"))
-            }
-        }
-    };
-}
-
-macro_rules! msg {
-    ($($arg:tt)*) => (
-        match writeln!(&mut ::std::io::stderr(), $($arg)* ) {
-            Ok(_) => {},
-            Err(x) => panic!("Unable to write to stderr: {}", x),
-        }
-    )
-}
-
-// For format_missing and last_pos, need to use the source callsite (if applicable).
-// Required as generated code spans aren't guaranteed to follow on from the last span.
-macro_rules! source {
-    ($this: ident, $sp: expr) => {
-        $sp.source_callsite()
-    };
-}
-
-pub fn mk_sp(lo: BytePos, hi: BytePos) -> Span {
-    Span::new(lo, hi, NO_EXPANSION)
-}
-
-// Return true if the given span does not intersect with file lines.
-macro_rules! out_of_file_lines_range {
-    ($self: ident, $span: expr) => {
-        !$self
-            .config
-            .file_lines()
-            .intersects(&$self.codemap.lookup_line_range($span))
-    };
-}
-
-macro_rules! skip_out_of_file_lines_range {
-    ($self: ident, $span: expr) => {
-        if out_of_file_lines_range!($self, $span) {
-            return None;
-        }
-    };
-}
-
-macro_rules! skip_out_of_file_lines_range_visitor {
-    ($self: ident, $span: expr) => {
-        if out_of_file_lines_range!($self, $span) {
-            $self.push_rewrite($span, None);
-            return;
-        }
-    };
-}
-
-// Wraps String in an Option. Returns Some when the string adheres to the
-// Rewrite constraints defined for the Rewrite trait and else otherwise.
-pub fn wrap_str(s: String, max_width: usize, shape: Shape) -> Option<String> {
-    if is_valid_str(&s, max_width, shape) {
-        Some(s)
-    } else {
-        None
-    }
-}
-
-fn is_valid_str(snippet: &str, max_width: usize, shape: Shape) -> bool {
-    if !snippet.is_empty() {
-        // First line must fits with `shape.width`.
-        if first_line_width(snippet) > shape.width {
-            return false;
-        }
-        // If the snippet does not include newline, we are done.
-        if first_line_width(snippet) == snippet.len() {
-            return true;
-        }
-        // The other lines must fit within the maximum width.
-        if snippet.lines().skip(1).any(|line| line.len() > max_width) {
-            return false;
-        }
-        // A special check for the last line, since the caller may
-        // place trailing characters on this line.
-        if last_line_width(snippet) > shape.used_width() + shape.width {
-            return false;
-        }
-    }
-    true
-}
-
-#[inline]
-pub fn colon_spaces(before: bool, after: bool) -> &'static str {
-    match (before, after) {
-        (true, true) => " : ",
-        (true, false) => " :",
-        (false, true) => ": ",
-        (false, false) => ":",
-    }
-}
-
-#[inline]
-pub fn paren_overhead(context: &RewriteContext) -> usize {
-    if context.config.spaces_within_parens_and_brackets() {
-        4
-    } else {
-        2
-    }
-}
-
-pub fn left_most_sub_expr(e: &ast::Expr) -> &ast::Expr {
-    match e.node {
-        ast::ExprKind::InPlace(ref e, _)
-        | ast::ExprKind::Call(ref e, _)
-        | ast::ExprKind::Binary(_, ref e, _)
-        | ast::ExprKind::Cast(ref e, _)
-        | ast::ExprKind::Type(ref e, _)
-        | ast::ExprKind::Assign(ref e, _)
-        | ast::ExprKind::AssignOp(_, ref e, _)
-        | ast::ExprKind::Field(ref e, _)
-        | ast::ExprKind::TupField(ref e, _)
-        | ast::ExprKind::Index(ref e, _)
-        | ast::ExprKind::Range(Some(ref e), _, _)
-        | ast::ExprKind::Try(ref e) => left_most_sub_expr(e),
-        _ => e,
-    }
-}
-
-// isatty shamelessly adapted from cargo.
-#[cfg(unix)]
-pub fn isatty() -> bool {
-    extern crate libc;
-
-    unsafe { libc::isatty(libc::STDOUT_FILENO) != 0 }
-}
-#[cfg(windows)]
-pub fn isatty() -> bool {
-    extern crate kernel32;
-    extern crate winapi;
-
-    unsafe {
-        let handle = kernel32::GetStdHandle(winapi::winbase::STD_OUTPUT_HANDLE);
-        let mut out = 0;
-        kernel32::GetConsoleMode(handle, &mut out) != 0
-    }
-}
-
-pub fn use_colored_tty(color: Color) -> bool {
-    match color {
-        Color::Always => true,
-        Color::Never => false,
-        Color::Auto => isatty(),
-    }
-}
-
-pub fn starts_with_newline(s: &str) -> bool {
-    s.starts_with('\n') || s.starts_with("\r\n")
-}
diff --git a/src/vertical.rs b/src/vertical.rs
deleted file mode 100644
index 2ccb5d81339..00000000000
--- a/src/vertical.rs
+++ /dev/null
@@ -1,290 +0,0 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Format with vertical alignment.
-
-use std::cmp;
-
-use syntax::ast;
-use syntax::codemap::{BytePos, Span};
-
-use codemap::SpanUtils;
-use comment::{combine_strs_with_missing_comments, contains_comment};
-use expr::rewrite_field;
-use items::{rewrite_struct_field, rewrite_struct_field_prefix};
-use lists::{definitive_tactic, itemize_list, write_list, ListFormatting, ListTactic, Separator,
-            SeparatorPlace};
-use rewrite::{Rewrite, RewriteContext};
-use shape::{Indent, Shape};
-use spanned::Spanned;
-use utils::{contains_skip, is_attributes_extendable, mk_sp};
-
-pub trait AlignedItem {
-    fn skip(&self) -> bool;
-    fn get_span(&self) -> Span;
-    fn rewrite_prefix(&self, context: &RewriteContext, shape: Shape) -> Option<String>;
-    fn rewrite_aligned_item(
-        &self,
-        context: &RewriteContext,
-        shape: Shape,
-        prefix_max_width: usize,
-    ) -> Option<String>;
-}
-
-impl AlignedItem for ast::StructField {
-    fn skip(&self) -> bool {
-        contains_skip(&self.attrs)
-    }
-
-    fn get_span(&self) -> Span {
-        self.span()
-    }
-
-    fn rewrite_prefix(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        let attrs_str = self.attrs.rewrite(context, shape)?;
-        let missing_span = if self.attrs.is_empty() {
-            mk_sp(self.span.lo(), self.span.lo())
-        } else {
-            mk_sp(self.attrs.last().unwrap().span.hi(), self.span.lo())
-        };
-        let attrs_extendable = self.ident.is_none() && is_attributes_extendable(&attrs_str);
-        rewrite_struct_field_prefix(context, self).and_then(|field_str| {
-            combine_strs_with_missing_comments(
-                context,
-                &attrs_str,
-                &field_str,
-                missing_span,
-                shape,
-                attrs_extendable,
-            )
-        })
-    }
-
-    fn rewrite_aligned_item(
-        &self,
-        context: &RewriteContext,
-        shape: Shape,
-        prefix_max_width: usize,
-    ) -> Option<String> {
-        rewrite_struct_field(context, self, shape, prefix_max_width)
-    }
-}
-
-impl AlignedItem for ast::Field {
-    fn skip(&self) -> bool {
-        contains_skip(&self.attrs)
-    }
-
-    fn get_span(&self) -> Span {
-        self.span()
-    }
-
-    fn rewrite_prefix(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        let attrs_str = self.attrs.rewrite(context, shape)?;
-        let name = &self.ident.node.to_string();
-        let missing_span = if self.attrs.is_empty() {
-            mk_sp(self.span.lo(), self.span.lo())
-        } else {
-            mk_sp(self.attrs.last().unwrap().span.hi(), self.span.lo())
-        };
-        combine_strs_with_missing_comments(
-            context,
-            &attrs_str,
-            name,
-            missing_span,
-            shape,
-            is_attributes_extendable(&attrs_str),
-        )
-    }
-
-    fn rewrite_aligned_item(
-        &self,
-        context: &RewriteContext,
-        shape: Shape,
-        prefix_max_width: usize,
-    ) -> Option<String> {
-        rewrite_field(context, self, shape, prefix_max_width)
-    }
-}
-
-pub fn rewrite_with_alignment<T: AlignedItem>(
-    fields: &[T],
-    context: &RewriteContext,
-    shape: Shape,
-    span: Span,
-    one_line_width: usize,
-) -> Option<String> {
-    let (spaces, group_index) = if context.config.struct_field_align_threshold() > 0 {
-        group_aligned_items(context, fields)
-    } else {
-        ("", fields.len() - 1)
-    };
-    let init = &fields[0..group_index + 1];
-    let rest = &fields[group_index + 1..];
-    let init_last_pos = if rest.is_empty() {
-        span.hi()
-    } else {
-        // Decide whether the missing comments should stick to init or rest.
-        let init_hi = init[init.len() - 1].get_span().hi();
-        let rest_lo = rest[0].get_span().lo();
-        let missing_span = mk_sp(init_hi, rest_lo);
-        let missing_span = mk_sp(
-            context.codemap.span_after(missing_span, ","),
-            missing_span.hi(),
-        );
-
-        let snippet = context.snippet(missing_span);
-        if snippet.trim_left().starts_with("//") {
-            let offset = snippet.lines().next().map_or(0, |l| l.len());
-            // 2 = "," + "\n"
-            init_hi + BytePos(offset as u32 + 2)
-        } else if snippet.trim_left().starts_with("/*") {
-            let comment_lines = snippet
-                .lines()
-                .position(|line| line.trim_right().ends_with("*/"))
-                .unwrap_or(0);
-
-            let offset = snippet
-                .lines()
-                .take(comment_lines + 1)
-                .collect::<Vec<_>>()
-                .join("\n")
-                .len();
-
-            init_hi + BytePos(offset as u32 + 2)
-        } else {
-            missing_span.lo()
-        }
-    };
-    let init_span = mk_sp(span.lo(), init_last_pos);
-    let one_line_width = if rest.is_empty() { one_line_width } else { 0 };
-    let result =
-        rewrite_aligned_items_inner(context, init, init_span, shape.indent, one_line_width)?;
-    if rest.is_empty() {
-        Some(result + spaces)
-    } else {
-        let rest_span = mk_sp(init_last_pos, span.hi());
-        let rest_str = rewrite_with_alignment(rest, context, shape, rest_span, one_line_width)?;
-        Some(
-            result + spaces + "\n"
-                + &shape
-                    .indent
-                    .block_indent(context.config)
-                    .to_string(context.config) + &rest_str,
-        )
-    }
-}
-
-fn struct_field_prefix_max_min_width<T: AlignedItem>(
-    context: &RewriteContext,
-    fields: &[T],
-    shape: Shape,
-) -> (usize, usize) {
-    fields
-        .iter()
-        .map(|field| {
-            field.rewrite_prefix(context, shape).and_then(|field_str| {
-                if field_str.contains('\n') {
-                    None
-                } else {
-                    Some(field_str.len())
-                }
-            })
-        })
-        .fold(Some((0, ::std::usize::MAX)), |acc, len| match (acc, len) {
-            (Some((max_len, min_len)), Some(len)) => {
-                Some((cmp::max(max_len, len), cmp::min(min_len, len)))
-            }
-            _ => None,
-        })
-        .unwrap_or((0, 0))
-}
-
-fn rewrite_aligned_items_inner<T: AlignedItem>(
-    context: &RewriteContext,
-    fields: &[T],
-    span: Span,
-    offset: Indent,
-    one_line_width: usize,
-) -> Option<String> {
-    let item_indent = offset.block_indent(context.config);
-    // 1 = ","
-    let item_shape = Shape::indented(item_indent, context.config).sub_width(1)?;
-    let (mut field_prefix_max_width, field_prefix_min_width) =
-        struct_field_prefix_max_min_width(context, fields, item_shape);
-    let max_diff = field_prefix_max_width
-        .checked_sub(field_prefix_min_width)
-        .unwrap_or(0);
-    if max_diff > context.config.struct_field_align_threshold() {
-        field_prefix_max_width = 0;
-    }
-
-    let items = itemize_list(
-        context.codemap,
-        fields.iter(),
-        "}",
-        ",",
-        |field| field.get_span().lo(),
-        |field| field.get_span().hi(),
-        |field| field.rewrite_aligned_item(context, item_shape, field_prefix_max_width),
-        span.lo(),
-        span.hi(),
-        false,
-    ).collect::<Vec<_>>();
-
-    let tactic = definitive_tactic(
-        &items,
-        ListTactic::HorizontalVertical,
-        Separator::Comma,
-        one_line_width,
-    );
-
-    let fmt = ListFormatting {
-        tactic,
-        separator: ",",
-        trailing_separator: context.config.trailing_comma(),
-        separator_place: SeparatorPlace::Back,
-        shape: item_shape,
-        ends_with_newline: true,
-        preserve_newline: true,
-        config: context.config,
-    };
-    write_list(&items, &fmt)
-}
-
-fn group_aligned_items<T: AlignedItem>(
-    context: &RewriteContext,
-    fields: &[T],
-) -> (&'static str, usize) {
-    let mut index = 0;
-    for i in 0..fields.len() - 1 {
-        if fields[i].skip() {
-            return ("", index);
-        }
-        // See if there are comments or empty lines between fields.
-        let span = mk_sp(fields[i].get_span().hi(), fields[i + 1].get_span().lo());
-        let snippet = context
-            .snippet(span)
-            .lines()
-            .skip(1)
-            .collect::<Vec<_>>()
-            .join("\n");
-        let spacings = if snippet.lines().rev().skip(1).any(|l| l.trim().is_empty()) {
-            "\n"
-        } else {
-            ""
-        };
-        if contains_comment(&snippet) || snippet.lines().count() > 1 {
-            return (spacings, index);
-        }
-        index += 1;
-    }
-    ("", index)
-}
diff --git a/src/visitor.rs b/src/visitor.rs
deleted file mode 100644
index cd6c0740ee6..00000000000
--- a/src/visitor.rs
+++ /dev/null
@@ -1,1113 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::cmp;
-
-use syntax::{ast, visit};
-use syntax::attr::{self, HasAttrs};
-use syntax::codemap::{self, BytePos, CodeMap, Pos, Span};
-use syntax::parse::ParseSess;
-
-use codemap::{LineRangeUtils, SpanUtils};
-use comment::{combine_strs_with_missing_comments, contains_comment, CodeCharKind,
-              CommentCodeSlices, FindUncommented};
-use comment::rewrite_comment;
-use config::{BraceStyle, Config};
-use expr::rewrite_literal;
-use items::{format_impl, format_trait, format_trait_alias, rewrite_associated_impl_type,
-            rewrite_associated_type, rewrite_type_alias, FnSig, StaticParts, StructParts};
-use lists::{itemize_list, write_list, DefinitiveListTactic, ListFormatting, SeparatorPlace,
-            SeparatorTactic};
-use macros::{rewrite_macro, rewrite_macro_def, MacroPosition};
-use regex::Regex;
-use rewrite::{Rewrite, RewriteContext};
-use shape::{Indent, Shape};
-use spanned::Spanned;
-use utils::{self, contains_skip, count_newlines, inner_attributes, mk_sp, ptr_vec_to_ref_vec};
-
-/// Returns attributes that are within `outer_span`.
-pub fn filter_inline_attrs(attrs: &[ast::Attribute], outer_span: Span) -> Vec<ast::Attribute> {
-    attrs
-        .iter()
-        .filter(|a| outer_span.lo() <= a.span.lo() && a.span.hi() <= outer_span.hi())
-        .cloned()
-        .collect()
-}
-
-/// Returns true for `mod foo;`, false for `mod foo { .. }`.
-fn is_mod_decl(item: &ast::Item) -> bool {
-    match item.node {
-        ast::ItemKind::Mod(ref m) => m.inner.hi() != item.span.hi(),
-        _ => false,
-    }
-}
-
-fn contains_macro_use_attr(attrs: &[ast::Attribute], span: Span) -> bool {
-    attr::contains_name(&filter_inline_attrs(attrs, span), "macro_use")
-}
-
-/// Returns true for `mod foo;` without any inline attributes.
-/// We cannot reorder modules with attributes because doing so can break the code.
-/// e.g. `#[macro_use]`.
-fn is_mod_decl_without_attr(item: &ast::Item) -> bool {
-    is_mod_decl(item) && !contains_macro_use_attr(&item.attrs, item.span())
-}
-
-fn is_use_item(item: &ast::Item) -> bool {
-    match item.node {
-        ast::ItemKind::Use(_) => true,
-        _ => false,
-    }
-}
-
-fn is_use_item_without_attr(item: &ast::Item) -> bool {
-    is_use_item(item) && !contains_macro_use_attr(&item.attrs, item.span())
-}
-
-fn is_extern_crate(item: &ast::Item) -> bool {
-    match item.node {
-        ast::ItemKind::ExternCrate(..) => true,
-        _ => false,
-    }
-}
-
-fn is_extern_crate_without_attr(item: &ast::Item) -> bool {
-    is_extern_crate(item) && !contains_macro_use_attr(&item.attrs, item.span())
-}
-
-/// Creates a string slice corresponding to the specified span.
-pub struct SnippetProvider<'a> {
-    /// A pointer to the content of the file we are formatting.
-    big_snippet: &'a str,
-    /// A position of the start of `big_snippet`, used as an offset.
-    start_pos: usize,
-}
-
-impl<'a> SnippetProvider<'a> {
-    pub fn span_to_snippet(&self, span: Span) -> Option<&str> {
-        let start_index = span.lo().to_usize().checked_sub(self.start_pos)?;
-        let end_index = span.hi().to_usize().checked_sub(self.start_pos)?;
-        Some(&self.big_snippet[start_index..end_index])
-    }
-
-    pub fn new(start_pos: BytePos, big_snippet: &'a str) -> Self {
-        let start_pos = start_pos.to_usize();
-        SnippetProvider {
-            big_snippet,
-            start_pos,
-        }
-    }
-}
-
-pub struct FmtVisitor<'a> {
-    pub parse_session: &'a ParseSess,
-    pub codemap: &'a CodeMap,
-    pub buffer: String,
-    pub last_pos: BytePos,
-    // FIXME: use an RAII util or closure for indenting
-    pub block_indent: Indent,
-    pub config: &'a Config,
-    pub is_if_else_block: bool,
-    pub snippet_provider: &'a SnippetProvider<'a>,
-    pub line_number: usize,
-    pub skipped_range: Vec<(usize, usize)>,
-}
-
-impl<'b, 'a: 'b> FmtVisitor<'a> {
-    pub fn shape(&self) -> Shape {
-        Shape::indented(self.block_indent, self.config)
-    }
-
-    fn visit_stmt(&mut self, stmt: &ast::Stmt) {
-        debug!(
-            "visit_stmt: {:?} {:?}",
-            self.codemap.lookup_char_pos(stmt.span.lo()),
-            self.codemap.lookup_char_pos(stmt.span.hi())
-        );
-
-        match stmt.node {
-            ast::StmtKind::Item(ref item) => {
-                self.visit_item(item);
-            }
-            ast::StmtKind::Local(..) | ast::StmtKind::Expr(..) | ast::StmtKind::Semi(..) => {
-                if contains_skip(get_attrs_from_stmt(stmt)) {
-                    self.push_skipped_with_span(stmt.span());
-                } else {
-                    let rewrite = stmt.rewrite(&self.get_context(), self.shape());
-                    self.push_rewrite(stmt.span(), rewrite)
-                }
-            }
-            ast::StmtKind::Mac(ref mac) => {
-                let (ref mac, _macro_style, ref attrs) = **mac;
-                if self.visit_attrs(attrs, ast::AttrStyle::Outer) {
-                    self.push_skipped_with_span(stmt.span());
-                } else {
-                    self.visit_mac(mac, None, MacroPosition::Statement);
-                }
-                self.format_missing(stmt.span.hi());
-            }
-        }
-    }
-
-    pub fn visit_block(
-        &mut self,
-        b: &ast::Block,
-        inner_attrs: Option<&[ast::Attribute]>,
-        has_braces: bool,
-    ) {
-        debug!(
-            "visit_block: {:?} {:?}",
-            self.codemap.lookup_char_pos(b.span.lo()),
-            self.codemap.lookup_char_pos(b.span.hi())
-        );
-
-        // Check if this block has braces.
-        let brace_compensation = BytePos(if has_braces { 1 } else { 0 });
-
-        self.last_pos = self.last_pos + brace_compensation;
-        self.block_indent = self.block_indent.block_indent(self.config);
-        self.push_str("{");
-
-        if self.config.remove_blank_lines_at_start_or_end_of_block() {
-            if let Some(first_stmt) = b.stmts.first() {
-                let attr_lo = inner_attrs
-                    .and_then(|attrs| inner_attributes(attrs).first().map(|attr| attr.span.lo()))
-                    .or_else(|| {
-                        // Attributes for an item in a statement position
-                        // do not belong to the statement. (rust-lang/rust#34459)
-                        if let ast::StmtKind::Item(ref item) = first_stmt.node {
-                            item.attrs.first()
-                        } else {
-                            first_stmt.attrs().first()
-                        }.and_then(|attr| {
-                            // Some stmts can have embedded attributes.
-                            // e.g. `match { #![attr] ... }`
-                            let attr_lo = attr.span.lo();
-                            if attr_lo < first_stmt.span.lo() {
-                                Some(attr_lo)
-                            } else {
-                                None
-                            }
-                        })
-                    });
-
-                let snippet = self.snippet(mk_sp(
-                    self.last_pos,
-                    attr_lo.unwrap_or(first_stmt.span.lo()),
-                ));
-                let len = CommentCodeSlices::new(snippet)
-                    .nth(0)
-                    .and_then(|(kind, _, s)| {
-                        if kind == CodeCharKind::Normal {
-                            s.rfind('\n')
-                        } else {
-                            None
-                        }
-                    });
-                if let Some(len) = len {
-                    self.last_pos = self.last_pos + BytePos::from_usize(len);
-                }
-            }
-        }
-
-        // Format inner attributes if available.
-        let skip_rewrite = if let Some(attrs) = inner_attrs {
-            self.visit_attrs(attrs, ast::AttrStyle::Inner)
-        } else {
-            false
-        };
-
-        if skip_rewrite {
-            self.push_rewrite(b.span, None);
-            self.close_block(false);
-            self.last_pos = source!(self, b.span).hi();
-            return;
-        }
-
-        self.walk_block_stmts(b);
-
-        if !b.stmts.is_empty() {
-            if let Some(expr) = utils::stmt_expr(&b.stmts[b.stmts.len() - 1]) {
-                if utils::semicolon_for_expr(&self.get_context(), expr) {
-                    self.push_str(";");
-                }
-            }
-        }
-
-        let mut remove_len = BytePos(0);
-        if self.config.remove_blank_lines_at_start_or_end_of_block() {
-            if let Some(stmt) = b.stmts.last() {
-                let snippet = self.snippet(mk_sp(
-                    stmt.span.hi(),
-                    source!(self, b.span).hi() - brace_compensation,
-                ));
-                let len = CommentCodeSlices::new(snippet)
-                    .last()
-                    .and_then(|(kind, _, s)| {
-                        if kind == CodeCharKind::Normal && s.trim().is_empty() {
-                            Some(s.len())
-                        } else {
-                            None
-                        }
-                    });
-                if let Some(len) = len {
-                    remove_len = BytePos::from_usize(len);
-                }
-            }
-        }
-
-        let unindent_comment = (self.is_if_else_block && !b.stmts.is_empty()) && {
-            let end_pos = source!(self, b.span).hi() - brace_compensation - remove_len;
-            let snippet = self.snippet(mk_sp(self.last_pos, end_pos));
-            snippet.contains("//") || snippet.contains("/*")
-        };
-        // FIXME: we should compress any newlines here to just one
-        if unindent_comment {
-            self.block_indent = self.block_indent.block_unindent(self.config);
-        }
-        self.format_missing_with_indent(
-            source!(self, b.span).hi() - brace_compensation - remove_len,
-        );
-        if unindent_comment {
-            self.block_indent = self.block_indent.block_indent(self.config);
-        }
-        self.close_block(unindent_comment);
-        self.last_pos = source!(self, b.span).hi();
-    }
-
-    // FIXME: this is a terrible hack to indent the comments between the last
-    // item in the block and the closing brace to the block's level.
-    // The closing brace itself, however, should be indented at a shallower
-    // level.
-    fn close_block(&mut self, unindent_comment: bool) {
-        let total_len = self.buffer.len();
-        let chars_too_many = if unindent_comment {
-            0
-        } else if self.config.hard_tabs() {
-            1
-        } else {
-            self.config.tab_spaces()
-        };
-        self.buffer.truncate(total_len - chars_too_many);
-        self.push_str("}");
-        self.block_indent = self.block_indent.block_unindent(self.config);
-    }
-
-    // Note that this only gets called for function definitions. Required methods
-    // on traits do not get handled here.
-    fn visit_fn(
-        &mut self,
-        fk: visit::FnKind,
-        generics: &ast::Generics,
-        fd: &ast::FnDecl,
-        s: Span,
-        defaultness: ast::Defaultness,
-        inner_attrs: Option<&[ast::Attribute]>,
-    ) {
-        let indent = self.block_indent;
-        let block;
-        let rewrite = match fk {
-            visit::FnKind::ItemFn(ident, _, _, _, _, b) | visit::FnKind::Method(ident, _, _, b) => {
-                block = b;
-                self.rewrite_fn(
-                    indent,
-                    ident,
-                    &FnSig::from_fn_kind(&fk, generics, fd, defaultness),
-                    mk_sp(s.lo(), b.span.lo()),
-                    b,
-                )
-            }
-            visit::FnKind::Closure(_) => unreachable!(),
-        };
-
-        if let Some(fn_str) = rewrite {
-            self.format_missing_with_indent(source!(self, s).lo());
-            self.push_str(&fn_str);
-            if let Some(c) = fn_str.chars().last() {
-                if c == '}' {
-                    self.last_pos = source!(self, block.span).hi();
-                    return;
-                }
-            }
-        } else {
-            self.format_missing(source!(self, block.span).lo());
-        }
-
-        self.last_pos = source!(self, block.span).lo();
-        self.visit_block(block, inner_attrs, true)
-    }
-
-    pub fn visit_item(&mut self, item: &ast::Item) {
-        skip_out_of_file_lines_range_visitor!(self, item.span);
-
-        // This is where we bail out if there is a skip attribute. This is only
-        // complex in the module case. It is complex because the module could be
-        // in a separate file and there might be attributes in both files, but
-        // the AST lumps them all together.
-        let filtered_attrs;
-        let mut attrs = &item.attrs;
-        match item.node {
-            // Module is inline, in this case we treat it like any other item.
-            _ if !is_mod_decl(item) => {
-                if self.visit_attrs(&item.attrs, ast::AttrStyle::Outer) {
-                    self.push_skipped_with_span(item.span());
-                    return;
-                }
-            }
-            // Module is not inline, but should be skipped.
-            ast::ItemKind::Mod(..) if contains_skip(&item.attrs) => {
-                return;
-            }
-            // Module is not inline and should not be skipped. We want
-            // to process only the attributes in the current file.
-            ast::ItemKind::Mod(..) => {
-                filtered_attrs = filter_inline_attrs(&item.attrs, item.span());
-                // Assert because if we should skip it should be caught by
-                // the above case.
-                assert!(!self.visit_attrs(&filtered_attrs, ast::AttrStyle::Outer));
-                attrs = &filtered_attrs;
-            }
-            _ => {
-                if self.visit_attrs(&item.attrs, ast::AttrStyle::Outer) {
-                    self.push_skipped_with_span(item.span());
-                    return;
-                }
-            }
-        }
-
-        match item.node {
-            ast::ItemKind::Use(ref tree) => self.format_import(item, tree),
-            ast::ItemKind::Impl(..) => {
-                let snippet = self.snippet(item.span);
-                let where_span_end = snippet
-                    .find_uncommented("{")
-                    .map(|x| (BytePos(x as u32)) + source!(self, item.span).lo());
-                let rw = format_impl(&self.get_context(), item, self.block_indent, where_span_end);
-                self.push_rewrite(item.span, rw);
-            }
-            ast::ItemKind::Trait(..) => {
-                let rw = format_trait(&self.get_context(), item, self.block_indent);
-                self.push_rewrite(item.span, rw);
-            }
-            ast::ItemKind::TraitAlias(ref generics, ref ty_param_bounds) => {
-                let shape = Shape::indented(self.block_indent, self.config);
-                let rw = format_trait_alias(
-                    &self.get_context(),
-                    item.ident,
-                    generics,
-                    ty_param_bounds,
-                    shape,
-                );
-                self.push_rewrite(item.span, rw);
-            }
-            ast::ItemKind::ExternCrate(_) => {
-                let rw = rewrite_extern_crate(&self.get_context(), item);
-                self.push_rewrite(item.span, rw);
-            }
-            ast::ItemKind::Struct(..) | ast::ItemKind::Union(..) => {
-                self.visit_struct(&StructParts::from_item(item));
-            }
-            ast::ItemKind::Enum(ref def, ref generics) => {
-                self.format_missing_with_indent(source!(self, item.span).lo());
-                self.visit_enum(item.ident, &item.vis, def, generics, item.span);
-                self.last_pos = source!(self, item.span).hi();
-            }
-            ast::ItemKind::Mod(ref module) => {
-                let is_inline = !is_mod_decl(item);
-                self.format_missing_with_indent(source!(self, item.span).lo());
-                self.format_mod(module, &item.vis, item.span, item.ident, attrs, is_inline);
-            }
-            ast::ItemKind::Mac(ref mac) => {
-                self.visit_mac(mac, Some(item.ident), MacroPosition::Item);
-            }
-            ast::ItemKind::ForeignMod(ref foreign_mod) => {
-                self.format_missing_with_indent(source!(self, item.span).lo());
-                self.format_foreign_mod(foreign_mod, item.span);
-            }
-            ast::ItemKind::Static(..) | ast::ItemKind::Const(..) => {
-                self.visit_static(&StaticParts::from_item(item));
-            }
-            ast::ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => {
-                self.visit_fn(
-                    visit::FnKind::ItemFn(item.ident, unsafety, constness, abi, &item.vis, body),
-                    generics,
-                    decl,
-                    item.span,
-                    ast::Defaultness::Final,
-                    Some(&item.attrs),
-                )
-            }
-            ast::ItemKind::Ty(ref ty, ref generics) => {
-                let rewrite = rewrite_type_alias(
-                    &self.get_context(),
-                    self.block_indent,
-                    item.ident,
-                    ty,
-                    generics,
-                    &item.vis,
-                    item.span,
-                );
-                self.push_rewrite(item.span, rewrite);
-            }
-            ast::ItemKind::GlobalAsm(..) => {
-                let snippet = Some(self.snippet(item.span).to_owned());
-                self.push_rewrite(item.span, snippet);
-            }
-            ast::ItemKind::MacroDef(ref def) => {
-                let rewrite = rewrite_macro_def(
-                    &self.get_context(),
-                    self.shape(),
-                    self.block_indent,
-                    def,
-                    item.ident,
-                    &item.vis,
-                    item.span,
-                );
-                self.push_rewrite(item.span, rewrite);
-            }
-        }
-    }
-
-    pub fn visit_trait_item(&mut self, ti: &ast::TraitItem) {
-        skip_out_of_file_lines_range_visitor!(self, ti.span);
-
-        if self.visit_attrs(&ti.attrs, ast::AttrStyle::Outer) {
-            self.push_skipped_with_span(ti.span());
-            return;
-        }
-
-        match ti.node {
-            ast::TraitItemKind::Const(..) => self.visit_static(&StaticParts::from_trait_item(ti)),
-            ast::TraitItemKind::Method(ref sig, None) => {
-                let indent = self.block_indent;
-                let rewrite =
-                    self.rewrite_required_fn(indent, ti.ident, sig, &ti.generics, ti.span);
-                self.push_rewrite(ti.span, rewrite);
-            }
-            ast::TraitItemKind::Method(ref sig, Some(ref body)) => {
-                self.visit_fn(
-                    visit::FnKind::Method(ti.ident, sig, None, body),
-                    &ti.generics,
-                    &sig.decl,
-                    ti.span,
-                    ast::Defaultness::Final,
-                    Some(&ti.attrs),
-                );
-            }
-            ast::TraitItemKind::Type(ref type_param_bounds, ref type_default) => {
-                let rewrite = rewrite_associated_type(
-                    ti.ident,
-                    type_default.as_ref(),
-                    Some(type_param_bounds),
-                    &self.get_context(),
-                    self.block_indent,
-                );
-                self.push_rewrite(ti.span, rewrite);
-            }
-            ast::TraitItemKind::Macro(ref mac) => {
-                self.visit_mac(mac, Some(ti.ident), MacroPosition::Item);
-            }
-        }
-    }
-
-    pub fn visit_impl_item(&mut self, ii: &ast::ImplItem) {
-        skip_out_of_file_lines_range_visitor!(self, ii.span);
-
-        if self.visit_attrs(&ii.attrs, ast::AttrStyle::Outer) {
-            self.push_skipped_with_span(ii.span());
-            return;
-        }
-
-        match ii.node {
-            ast::ImplItemKind::Method(ref sig, ref body) => {
-                self.visit_fn(
-                    visit::FnKind::Method(ii.ident, sig, Some(&ii.vis), body),
-                    &ii.generics,
-                    &sig.decl,
-                    ii.span,
-                    ii.defaultness,
-                    Some(&ii.attrs),
-                );
-            }
-            ast::ImplItemKind::Const(..) => self.visit_static(&StaticParts::from_impl_item(ii)),
-            ast::ImplItemKind::Type(ref ty) => {
-                let rewrite = rewrite_associated_impl_type(
-                    ii.ident,
-                    ii.defaultness,
-                    Some(ty),
-                    None,
-                    &self.get_context(),
-                    self.block_indent,
-                );
-                self.push_rewrite(ii.span, rewrite);
-            }
-            ast::ImplItemKind::Macro(ref mac) => {
-                self.visit_mac(mac, Some(ii.ident), MacroPosition::Item);
-            }
-        }
-    }
-
-    fn visit_mac(&mut self, mac: &ast::Mac, ident: Option<ast::Ident>, pos: MacroPosition) {
-        skip_out_of_file_lines_range_visitor!(self, mac.span);
-
-        // 1 = ;
-        let shape = self.shape().sub_width(1).unwrap();
-        let rewrite = rewrite_macro(mac, ident, &self.get_context(), shape, pos);
-        self.push_rewrite(mac.span, rewrite);
-    }
-
-    pub fn push_str(&mut self, s: &str) {
-        self.line_number += count_newlines(s);
-        self.buffer.push_str(s);
-    }
-
-    fn push_rewrite_inner(&mut self, span: Span, rewrite: Option<String>) {
-        if let Some(ref s) = rewrite {
-            self.push_str(s);
-        } else {
-            let snippet = self.snippet(span);
-            self.push_str(snippet);
-        }
-        self.last_pos = source!(self, span).hi();
-    }
-
-    pub fn push_rewrite(&mut self, span: Span, rewrite: Option<String>) {
-        self.format_missing_with_indent(source!(self, span).lo());
-        self.push_rewrite_inner(span, rewrite);
-    }
-
-    pub fn push_skipped_with_span(&mut self, span: Span) {
-        self.format_missing_with_indent(source!(self, span).lo());
-        let lo = self.line_number + 1;
-        self.push_rewrite_inner(span, None);
-        let hi = self.line_number + 1;
-        self.skipped_range.push((lo, hi));
-    }
-
-    pub fn from_context(ctx: &'a RewriteContext) -> FmtVisitor<'a> {
-        FmtVisitor::from_codemap(ctx.parse_session, ctx.config, ctx.snippet_provider)
-    }
-
-    pub fn from_codemap(
-        parse_session: &'a ParseSess,
-        config: &'a Config,
-        snippet_provider: &'a SnippetProvider,
-    ) -> FmtVisitor<'a> {
-        FmtVisitor {
-            parse_session,
-            codemap: parse_session.codemap(),
-            buffer: String::with_capacity(snippet_provider.big_snippet.len() * 2),
-            last_pos: BytePos(0),
-            block_indent: Indent::empty(),
-            config,
-            is_if_else_block: false,
-            snippet_provider,
-            line_number: 0,
-            skipped_range: vec![],
-        }
-    }
-
-    pub fn opt_snippet(&'b self, span: Span) -> Option<&'a str> {
-        self.snippet_provider.span_to_snippet(span)
-    }
-
-    pub fn snippet(&'b self, span: Span) -> &'a str {
-        self.opt_snippet(span).unwrap()
-    }
-
-    // Returns true if we should skip the following item.
-    pub fn visit_attrs(&mut self, attrs: &[ast::Attribute], style: ast::AttrStyle) -> bool {
-        if contains_skip(attrs) {
-            return true;
-        }
-
-        let attrs: Vec<_> = attrs.iter().filter(|a| a.style == style).cloned().collect();
-        if attrs.is_empty() {
-            return false;
-        }
-
-        let rewrite = attrs.rewrite(&self.get_context(), self.shape());
-        let span = mk_sp(attrs[0].span.lo(), attrs[attrs.len() - 1].span.hi());
-        self.push_rewrite(span, rewrite);
-
-        false
-    }
-
-    fn reorder_items<F>(&mut self, items_left: &[&ast::Item], is_item: &F, in_group: bool) -> usize
-    where
-        F: Fn(&ast::Item) -> bool,
-    {
-        let mut last = self.codemap.lookup_line_range(items_left[0].span());
-        let item_length = items_left
-            .iter()
-            .take_while(|ppi| {
-                is_item(&***ppi) && (!in_group || {
-                    let current = self.codemap.lookup_line_range(ppi.span());
-                    let in_same_group = current.lo < last.hi + 2;
-                    last = current;
-                    in_same_group
-                })
-            })
-            .count();
-        let items = &items_left[..item_length];
-
-        let at_least_one_in_file_lines = items
-            .iter()
-            .any(|item| !out_of_file_lines_range!(self, item.span));
-
-        if at_least_one_in_file_lines {
-            self.format_imports(items);
-        } else {
-            for item in items {
-                self.push_rewrite(item.span, None);
-            }
-        }
-
-        item_length
-    }
-
-    fn walk_items(&mut self, mut items_left: &[&ast::Item]) {
-        macro try_reorder_items_with($reorder: ident, $in_group: ident, $pred: ident) {
-            if self.config.$reorder() && $pred(&*items_left[0]) {
-                let used_items_len =
-                    self.reorder_items(items_left, &$pred, self.config.$in_group());
-                let (_, rest) = items_left.split_at(used_items_len);
-                items_left = rest;
-                continue;
-            }
-        }
-
-        while !items_left.is_empty() {
-            // If the next item is a `use`, `extern crate` or `mod`, then extract it and any
-            // subsequent items that have the same item kind to be reordered within
-            // `format_imports`. Otherwise, just format the next item for output.
-            {
-                try_reorder_items_with!(
-                    reorder_imports,
-                    reorder_imports_in_group,
-                    is_use_item_without_attr
-                );
-                try_reorder_items_with!(
-                    reorder_extern_crates,
-                    reorder_extern_crates_in_group,
-                    is_extern_crate_without_attr
-                );
-                try_reorder_items_with!(reorder_modules, reorder_modules, is_mod_decl_without_attr);
-            }
-            // Reaching here means items were not reordered. There must be at least
-            // one item left in `items_left`, so calling `unwrap()` here is safe.
-            let (item, rest) = items_left.split_first().unwrap();
-            self.visit_item(item);
-            items_left = rest;
-        }
-    }
-
-    fn walk_mod_items(&mut self, m: &ast::Mod) {
-        self.walk_items(&ptr_vec_to_ref_vec(&m.items));
-    }
-
-    fn walk_stmts(&mut self, stmts: &[ast::Stmt]) {
-        fn to_stmt_item(stmt: &ast::Stmt) -> Option<&ast::Item> {
-            match stmt.node {
-                ast::StmtKind::Item(ref item) => Some(&**item),
-                _ => None,
-            }
-        }
-
-        if stmts.is_empty() {
-            return;
-        }
-
-        // Extract leading `use ...;`.
-        let items: Vec<_> = stmts
-            .iter()
-            .take_while(|stmt| to_stmt_item(stmt).map_or(false, is_use_item))
-            .filter_map(|stmt| to_stmt_item(stmt))
-            .collect();
-
-        if items.is_empty() {
-            self.visit_stmt(&stmts[0]);
-            self.walk_stmts(&stmts[1..]);
-        } else {
-            self.walk_items(&items);
-            self.walk_stmts(&stmts[items.len()..]);
-        }
-    }
-
-    fn walk_block_stmts(&mut self, b: &ast::Block) {
-        self.walk_stmts(&b.stmts)
-    }
-
-    fn format_mod(
-        &mut self,
-        m: &ast::Mod,
-        vis: &ast::Visibility,
-        s: Span,
-        ident: ast::Ident,
-        attrs: &[ast::Attribute],
-        is_internal: bool,
-    ) {
-        self.push_str(&*utils::format_visibility(vis));
-        self.push_str("mod ");
-        self.push_str(&ident.to_string());
-
-        if is_internal {
-            match self.config.brace_style() {
-                BraceStyle::AlwaysNextLine => {
-                    let sep_str = format!("\n{}{{", self.block_indent.to_string(self.config));
-                    self.push_str(&sep_str);
-                }
-                _ => self.push_str(" {"),
-            }
-            // Hackery to account for the closing }.
-            let mod_lo = self.codemap.span_after(source!(self, s), "{");
-            let body_snippet =
-                self.snippet(mk_sp(mod_lo, source!(self, m.inner).hi() - BytePos(1)));
-            let body_snippet = body_snippet.trim();
-            if body_snippet.is_empty() {
-                self.push_str("}");
-            } else {
-                self.last_pos = mod_lo;
-                self.block_indent = self.block_indent.block_indent(self.config);
-                self.visit_attrs(attrs, ast::AttrStyle::Inner);
-                self.walk_mod_items(m);
-                self.format_missing_with_indent(source!(self, m.inner).hi() - BytePos(1));
-                self.close_block(false);
-            }
-            self.last_pos = source!(self, m.inner).hi();
-        } else {
-            self.push_str(";");
-            self.last_pos = source!(self, s).hi();
-        }
-    }
-
-    pub fn format_separate_mod(&mut self, m: &ast::Mod, filemap: &codemap::FileMap) {
-        self.block_indent = Indent::empty();
-        self.walk_mod_items(m);
-        self.format_missing_with_indent(filemap.end_pos);
-    }
-
-    pub fn skip_empty_lines(&mut self, end_pos: BytePos) {
-        while let Some(pos) = self.codemap
-            .opt_span_after(mk_sp(self.last_pos, end_pos), "\n")
-        {
-            if let Some(snippet) = self.opt_snippet(mk_sp(self.last_pos, pos)) {
-                if snippet.trim().is_empty() {
-                    self.last_pos = pos;
-                } else {
-                    return;
-                }
-            }
-        }
-    }
-
-    pub fn get_context(&self) -> RewriteContext {
-        RewriteContext {
-            parse_session: self.parse_session,
-            codemap: self.codemap,
-            config: self.config,
-            inside_macro: false,
-            use_block: false,
-            is_if_else_block: false,
-            force_one_line_chain: false,
-            snippet_provider: self.snippet_provider,
-        }
-    }
-}
-
-impl Rewrite for ast::NestedMetaItem {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        match self.node {
-            ast::NestedMetaItemKind::MetaItem(ref meta_item) => meta_item.rewrite(context, shape),
-            ast::NestedMetaItemKind::Literal(ref l) => rewrite_literal(context, l, shape),
-        }
-    }
-}
-
-impl Rewrite for ast::MetaItem {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        Some(match self.node {
-            ast::MetaItemKind::Word => String::from(&*self.name.as_str()),
-            ast::MetaItemKind::List(ref list) => {
-                let name = self.name.as_str();
-                // 1 = `(`, 2 = `]` and `)`
-                let item_shape = shape
-                    .visual_indent(0)
-                    .shrink_left(name.len() + 1)
-                    .and_then(|s| s.sub_width(2))?;
-                let items = itemize_list(
-                    context.codemap,
-                    list.iter(),
-                    ")",
-                    ",",
-                    |nested_meta_item| nested_meta_item.span.lo(),
-                    |nested_meta_item| nested_meta_item.span.hi(),
-                    |nested_meta_item| nested_meta_item.rewrite(context, item_shape),
-                    self.span.lo(),
-                    self.span.hi(),
-                    false,
-                );
-                let item_vec = items.collect::<Vec<_>>();
-                let fmt = ListFormatting {
-                    tactic: DefinitiveListTactic::Mixed,
-                    separator: ",",
-                    trailing_separator: SeparatorTactic::Never,
-                    separator_place: SeparatorPlace::Back,
-                    shape: item_shape,
-                    ends_with_newline: false,
-                    preserve_newline: false,
-                    config: context.config,
-                };
-                format!("{}({})", name, write_list(&item_vec, &fmt)?)
-            }
-            ast::MetaItemKind::NameValue(ref literal) => {
-                let name = self.name.as_str();
-                // 3 = ` = `
-                let lit_shape = shape.shrink_left(name.len() + 3)?;
-                let value = rewrite_literal(context, literal, lit_shape)?;
-                format!("{} = {}", name, value)
-            }
-        })
-    }
-}
-
-impl Rewrite for ast::Attribute {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        let prefix = match self.style {
-            ast::AttrStyle::Inner => "#!",
-            ast::AttrStyle::Outer => "#",
-        };
-        let snippet = context.snippet(self.span);
-        if self.is_sugared_doc {
-            let doc_shape = Shape {
-                width: cmp::min(shape.width, context.config.comment_width())
-                    .checked_sub(shape.indent.width())
-                    .unwrap_or(0),
-                ..shape
-            };
-            rewrite_comment(snippet, false, doc_shape, context.config)
-        } else {
-            if contains_comment(snippet) {
-                return Some(snippet.to_owned());
-            }
-            // 1 = `[`
-            let shape = shape.offset_left(prefix.len() + 1)?;
-            self.meta()?
-                .rewrite(context, shape)
-                .map(|rw| format!("{}[{}]", prefix, rw))
-        }
-    }
-}
-
-/// Returns the first group of attributes that fills the given predicate.
-/// We consider two doc comments are in different group if they are separated by normal comments.
-fn take_while_with_pred<'a, P>(
-    context: &RewriteContext,
-    attrs: &'a [ast::Attribute],
-    pred: P,
-) -> &'a [ast::Attribute]
-where
-    P: Fn(&ast::Attribute) -> bool,
-{
-    let mut last_index = 0;
-    let mut iter = attrs.iter().enumerate().peekable();
-    while let Some((i, attr)) = iter.next() {
-        if !pred(attr) {
-            break;
-        }
-        if let Some(&(_, next_attr)) = iter.peek() {
-            // Extract comments between two attributes.
-            let span_between_attr = mk_sp(attr.span.hi(), next_attr.span.lo());
-            let snippet = context.snippet(span_between_attr);
-            if count_newlines(snippet) >= 2 || snippet.contains('/') {
-                break;
-            }
-        }
-        last_index = i;
-    }
-    if last_index == 0 {
-        &[]
-    } else {
-        &attrs[..last_index + 1]
-    }
-}
-
-fn rewrite_first_group_attrs(
-    context: &RewriteContext,
-    attrs: &[ast::Attribute],
-    shape: Shape,
-) -> Option<(usize, String)> {
-    if attrs.is_empty() {
-        return Some((0, String::new()));
-    }
-    // Rewrite doc comments
-    let sugared_docs = take_while_with_pred(context, attrs, |a| a.is_sugared_doc);
-    if !sugared_docs.is_empty() {
-        let snippet = sugared_docs
-            .iter()
-            .map(|a| context.snippet(a.span))
-            .collect::<Vec<_>>()
-            .join("\n");
-        return Some((
-            sugared_docs.len(),
-            rewrite_comment(&snippet, false, shape, context.config)?,
-        ));
-    }
-    // Rewrite `#[derive(..)]`s.
-    if context.config.merge_derives() {
-        let derives = take_while_with_pred(context, attrs, is_derive);
-        if !derives.is_empty() {
-            let mut derive_args = vec![];
-            for derive in derives {
-                derive_args.append(&mut get_derive_args(context, derive)?);
-            }
-            return Some((derives.len(), format_derive(context, &derive_args, shape)?));
-        }
-    }
-    // Rewrite the first attribute.
-    Some((1, attrs[0].rewrite(context, shape)?))
-}
-
-fn has_newlines_before_after_comment(comment: &str) -> (&str, &str) {
-    // Look at before and after comment and see if there are any empty lines.
-    let comment_begin = comment.chars().position(|c| c == '/');
-    let len = comment_begin.unwrap_or_else(|| comment.len());
-    let mlb = count_newlines(&comment[..len]) > 1;
-    let mla = if comment_begin.is_none() {
-        mlb
-    } else {
-        let comment_end = comment.chars().rev().position(|c| !c.is_whitespace());
-        let len = comment_end.unwrap();
-        comment
-            .chars()
-            .rev()
-            .take(len)
-            .filter(|c| *c == '\n')
-            .count() > 1
-    };
-    (if mlb { "\n" } else { "" }, if mla { "\n" } else { "" })
-}
-
-impl<'a> Rewrite for [ast::Attribute] {
-    fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        if self.is_empty() {
-            return Some(String::new());
-        }
-        let (first_group_len, first_group_str) = rewrite_first_group_attrs(context, self, shape)?;
-        if self.len() == 1 || first_group_len == self.len() {
-            Some(first_group_str)
-        } else {
-            let rest_str = self[first_group_len..].rewrite(context, shape)?;
-            let missing_span = mk_sp(
-                self[first_group_len - 1].span.hi(),
-                self[first_group_len].span.lo(),
-            );
-            // Preserve an empty line before/after doc comments.
-            if self[0].is_sugared_doc || self[first_group_len].is_sugared_doc {
-                let snippet = context.snippet(missing_span);
-                let (mla, mlb) = has_newlines_before_after_comment(snippet);
-                let comment = ::comment::recover_missing_comment_in_span(
-                    missing_span,
-                    shape.with_max_width(context.config),
-                    context,
-                    0,
-                )?;
-                let comment = if comment.is_empty() {
-                    format!("\n{}", mlb)
-                } else {
-                    format!("{}{}\n{}", mla, comment, mlb)
-                };
-                Some(format!(
-                    "{}{}{}{}",
-                    first_group_str,
-                    comment,
-                    shape.indent.to_string(context.config),
-                    rest_str
-                ))
-            } else {
-                combine_strs_with_missing_comments(
-                    context,
-                    &first_group_str,
-                    &rest_str,
-                    missing_span,
-                    shape,
-                    false,
-                )
-            }
-        }
-    }
-}
-
-// Format `#[derive(..)]`, using visual indent & mixed style when we need to go multiline.
-fn format_derive(context: &RewriteContext, derive_args: &[&str], shape: Shape) -> Option<String> {
-    let mut result = String::with_capacity(128);
-    result.push_str("#[derive(");
-    // 11 = `#[derive()]`
-    let initial_budget = shape.width.checked_sub(11)?;
-    let mut budget = initial_budget;
-    let num = derive_args.len();
-    for (i, a) in derive_args.iter().enumerate() {
-        // 2 = `, ` or `)]`
-        let width = a.len() + 2;
-        if width > budget {
-            if i > 0 {
-                // Remove trailing whitespace.
-                result.pop();
-            }
-            result.push('\n');
-            // 9 = `#[derive(`
-            result.push_str(&(shape.indent + 9).to_string(context.config));
-            budget = initial_budget;
-        } else {
-            budget = budget.checked_sub(width).unwrap_or(0);
-        }
-        result.push_str(a);
-        if i != num - 1 {
-            result.push_str(", ")
-        }
-    }
-    result.push_str(")]");
-    Some(result)
-}
-
-fn is_derive(attr: &ast::Attribute) -> bool {
-    attr.check_name("derive")
-}
-
-/// Returns the arguments of `#[derive(...)]`.
-fn get_derive_args<'a>(context: &'a RewriteContext, attr: &ast::Attribute) -> Option<Vec<&'a str>> {
-    attr.meta_item_list().map(|meta_item_list| {
-        meta_item_list
-            .iter()
-            .map(|nested_meta_item| context.snippet(nested_meta_item.span))
-            .collect()
-    })
-}
-
-// Rewrite `extern crate foo;` WITHOUT attributes.
-pub fn rewrite_extern_crate(context: &RewriteContext, item: &ast::Item) -> Option<String> {
-    assert!(is_extern_crate(item));
-    let new_str = context.snippet(item.span);
-    Some(if contains_comment(new_str) {
-        new_str.to_owned()
-    } else {
-        let no_whitespace = &new_str.split_whitespace().collect::<Vec<&str>>().join(" ");
-        String::from(&*Regex::new(r"\s;").unwrap().replace(no_whitespace, ";"))
-    })
-}
-
-fn get_attrs_from_stmt(stmt: &ast::Stmt) -> &[ast::Attribute] {
-    match stmt.node {
-        ast::StmtKind::Local(ref local) => &local.attrs,
-        ast::StmtKind::Item(ref item) => &item.attrs,
-        ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => &expr.attrs,
-        ast::StmtKind::Mac(ref mac) => &mac.2,
-    }
-}