diff --git a/src/expr.rs b/src/expr.rs
index 4a415a5cc82..318ec8e59b5 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -1887,13 +1887,11 @@ fn rewrite_index(expr: &ast::Expr,
         ("[", "]")
     };
 
-    let budget = shape
-        .width
-        .checked_sub(expr_str.len() + lbr.len() + rbr.len())
-        .unwrap_or(0);
-    let index_str = index.rewrite(context, Shape::legacy(budget, shape.indent));
-    if let Some(index_str) = index_str {
-        return Some(format!("{}{}{}{}", expr_str, lbr, index_str, rbr));
+    let offset = expr_str.len() + lbr.len();
+    if let Some(index_shape) = shape.visual_indent(offset).sub_width(offset + rbr.len()) {
+        if let Some(index_str) = index.rewrite(context, index_shape) {
+            return Some(format!("{}{}{}{}", expr_str, lbr, index_str, rbr));
+        }
     }
 
     let indent = shape.indent.block_indent(&context.config);
diff --git a/src/items.rs b/src/items.rs
index 37ffb4792eb..34d2b6ea530 100644
--- a/src/items.rs
+++ b/src/items.rs
@@ -1564,7 +1564,12 @@ fn rewrite_fn_base(context: &RewriteContext,
 
     // Args.
     let (mut one_line_budget, mut multi_line_budget, mut arg_indent) =
-        try_opt!(compute_budgets_for_args(context, &result, indent, ret_str_len, newline_brace));
+        try_opt!(compute_budgets_for_args(context,
+                                          &result,
+                                          indent,
+                                          ret_str_len,
+                                          newline_brace,
+                                          has_braces));
 
     if context.config.fn_args_layout() == IndentStyle::Block {
         arg_indent = indent.block_indent(context.config);
@@ -1906,7 +1911,8 @@ fn compute_budgets_for_args(context: &RewriteContext,
                             result: &str,
                             indent: Indent,
                             ret_str_len: usize,
-                            newline_brace: bool)
+                            newline_brace: bool,
+                            has_braces: bool)
                             -> Option<((usize, usize, Indent))> {
     debug!("compute_budgets_for_args {} {:?}, {}, {}",
            result.len(),
@@ -1915,10 +1921,17 @@ fn compute_budgets_for_args(context: &RewriteContext,
            newline_brace);
     // Try keeping everything on the same line.
     if !result.contains('\n') {
-        // 3 = `() `, space is before ret_string.
-        let mut used_space = indent.width() + result.len() + ret_str_len + 3;
-        if !newline_brace {
-            used_space += 2;
+        // 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
             .config
diff --git a/tests/source/issue-1049.rs b/tests/source/issue-1049.rs
index a0240b83b63..03f10a1ba38 100644
--- a/tests/source/issue-1049.rs
+++ b/tests/source/issue-1049.rs
@@ -14,3 +14,5 @@ impl Handle {
 fn veeeeeeeeeeeeeeeeeeeeery_long_name(a: FirstTypeeeeeeeeee, b: SecondTypeeeeeeeeeeeeeeeeeeeeeee) {}
 
 fn veeeeeeeeeeeeeeeeeeeeeery_long_name(a: FirstTypeeeeeeeeee, b: SecondTypeeeeeeeeeeeeeeeeeeeeeee) {}
+
+fn veeeeeeeeeeeeeeeeeeeeeeery_long_name(a: FirstTypeeeeeeeeee, b: SecondTypeeeeeeeeeeeeeeeeeeeeeee) {}
diff --git a/tests/target/chains-visual.rs b/tests/target/chains-visual.rs
index 2763b339084..52d271a4469 100644
--- a/tests/target/chains-visual.rs
+++ b/tests/target/chains-visual.rs
@@ -83,9 +83,9 @@ fn floaters() {
             PushParam => {
                 // params are 1-indexed
                 stack.push(mparams[match cur.to_digit(10) {
-                               Some(d) => d as usize - 1,
-                               None => return Err("bad param number".to_owned()),
-                           }]
+                                       Some(d) => d as usize - 1,
+                                       None => return Err("bad param number".to_owned()),
+                                   }]
                            .clone());
             }
         }
diff --git a/tests/target/chains.rs b/tests/target/chains.rs
index 80b02482991..fb6ee2f885f 100644
--- a/tests/target/chains.rs
+++ b/tests/target/chains.rs
@@ -82,9 +82,9 @@ fn floaters() {
             PushParam => {
                 // params are 1-indexed
                 stack.push(mparams[match cur.to_digit(10) {
-                    Some(d) => d as usize - 1,
-                    None => return Err("bad param number".to_owned()),
-                }].clone());
+                                       Some(d) => d as usize - 1,
+                                       None => return Err("bad param number".to_owned()),
+                                   }].clone());
             }
         }
     }
diff --git a/tests/target/hard-tabs.rs b/tests/target/hard-tabs.rs
index 8782ecd87f3..b176820c3e6 100644
--- a/tests/target/hard-tabs.rs
+++ b/tests/target/hard-tabs.rs
@@ -16,17 +16,7 @@ fn main() {
 		..something
 	};
 
-	fn foo(a: i32,
-	       a: i32,
-	       a: i32,
-	       a: i32,
-	       a: i32,
-	       a: i32,
-	       a: i32,
-	       a: i32,
-	       a: i32,
-	       a: i32,
-	       a: i32) {
+	fn foo(a: i32, a: i32, a: i32, a: i32, a: i32, a: i32, a: i32, a: i32, a: i32, a: i32, a: i32) {
 	}
 
 	let str = "AAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAa";
diff --git a/tests/target/issue-1049.rs b/tests/target/issue-1049.rs
index fac49b80b51..020ac6ff0d9 100644
--- a/tests/target/issue-1049.rs
+++ b/tests/target/issue-1049.rs
@@ -16,6 +16,9 @@ impl Handle {
 // Long function without return type that should not be reformated.
 fn veeeeeeeeeeeeeeeeeeeeery_long_name(a: FirstTypeeeeeeeeee, b: SecondTypeeeeeeeeeeeeeeeeeeeeeee) {}
 
-fn veeeeeeeeeeeeeeeeeeeeeery_long_name(a: FirstTypeeeeeeeeee,
-                                       b: SecondTypeeeeeeeeeeeeeeeeeeeeeee) {
+fn veeeeeeeeeeeeeeeeeeeeeery_long_name(a: FirstTypeeeeeeeeee, b: SecondTypeeeeeeeeeeeeeeeeeeeeeee) {
+}
+
+fn veeeeeeeeeeeeeeeeeeeeeeery_long_name(a: FirstTypeeeeeeeeee,
+                                        b: SecondTypeeeeeeeeeeeeeeeeeeeeeee) {
 }
diff --git a/tests/target/issue-1247.rs b/tests/target/issue-1247.rs
new file mode 100644
index 00000000000..427a8076ad5
--- /dev/null
+++ b/tests/target/issue-1247.rs
@@ -0,0 +1,7 @@
+// rustfmt-max_width: 80
+
+fn foo() {
+    polyfill::slice::fill(&mut self.pending[padding_pos..
+                                            (self.algorithm.block_len - 8)],
+                          0);
+}