about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/chains.rs38
-rw-r--r--src/comment.rs22
-rw-r--r--src/expr.rs304
-rw-r--r--src/imports.rs40
-rw-r--r--src/items.rs322
-rw-r--r--src/lists.rs25
-rw-r--r--src/macros.rs43
-rw-r--r--src/patterns.rs45
-rw-r--r--src/shape.rs4
-rw-r--r--src/string.rs2
-rw-r--r--src/types.rs226
-rw-r--r--src/utils.rs9
-rw-r--r--src/vertical.rs23
-rw-r--r--src/visitor.rs30
14 files changed, 457 insertions, 676 deletions
diff --git a/src/chains.rs b/src/chains.rs
index 23c311b9589..74c43d783b7 100644
--- a/src/chains.rs
+++ b/src/chains.rs
@@ -110,11 +110,9 @@ pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) -
     } else {
         shape
     };
-    let parent_rewrite = try_opt!(
-        parent
-            .rewrite(context, parent_shape)
-            .map(|parent_rw| parent_rw + &repeat_try(prefix_try_num))
-    );
+    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();
 
@@ -146,8 +144,8 @@ pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) -
         let overhead = last_line_width(&parent_rewrite);
         let offset = parent_rewrite.lines().rev().next().unwrap().trim().len();
         match context.config.chain_indent() {
-            IndentStyle::Visual => try_opt!(parent_shape.offset_left(overhead)),
-            IndentStyle::Block => try_opt!(parent_shape.block().offset_left(offset)),
+            IndentStyle::Visual => parent_shape.offset_left(overhead)?,
+            IndentStyle::Block => parent_shape.block().offset_left(offset)?,
         }
     } else {
         other_child_shape
@@ -165,11 +163,9 @@ pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) -
     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 = try_opt!(
-        iter.map(|(e, shape)| {
-            rewrite_chain_subexpr(e, total_span, context, shape)
-        }).collect::<Option<Vec<_>>>()
-    );
+    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_subexr = last_line_extendable(&parent_rewrite) && rewrites.is_empty();
@@ -187,7 +183,7 @@ pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) -
         && rewrites.iter().all(|s| !s.contains('\n'))
         && almost_total < one_line_budget;
     let rewrite_last = || rewrite_chain_subexpr(last_subexpr, total_span, context, nested_shape);
-    let (last_subexpr_str, fits_single_line) = try_opt!(if all_in_one_line || extend_last_subexr {
+    let (last_subexpr_str, fits_single_line) = if all_in_one_line || extend_last_subexr {
         parent_shape.offset_left(almost_total).map(|shape| {
             if let Some(rw) = rewrite_chain_subexpr(last_subexpr, total_span, context, shape) {
                 let line_count = rw.lines().count();
@@ -207,11 +203,11 @@ pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) -
             } else {
                 (rewrite_last(), false)
             }
-        })
+        })?
     } else {
-        Some((rewrite_last(), false))
-    });
-    rewrites.push(try_opt!(last_subexpr_str));
+        (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.
@@ -288,7 +284,7 @@ fn rewrite_try(
     context: &RewriteContext,
     shape: Shape,
 ) -> Option<String> {
-    let sub_expr = try_opt!(expr.rewrite(context, try_opt!(shape.sub_width(try_count))));
+    let sub_expr = expr.rewrite(context, shape.sub_width(try_count)?)?;
     Some(format!("{}{}", sub_expr, repeat_try(try_count)))
 }
 
@@ -472,8 +468,10 @@ fn rewrite_method_call(
     let (lo, type_str) = if types.is_empty() {
         (args[0].span.hi(), String::new())
     } else {
-        let type_list: Vec<_> =
-            try_opt!(types.iter().map(|ty| ty.rewrite(context, shape)).collect());
+        let type_list = types
+            .iter()
+            .map(|ty| ty.rewrite(context, shape))
+            .collect::<Option<Vec<_>>>()?;
 
         let type_str = if context.config.spaces_within_angle_brackets() && !type_list.is_empty() {
             format!("::< {} >", type_list.join(", "))
diff --git a/src/comment.rs b/src/comment.rs
index f74684e5862..f966d658dc8 100644
--- a/src/comment.rs
+++ b/src/comment.rs
@@ -152,7 +152,7 @@ pub fn combine_strs_with_missing_comments(
         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 = try_opt!(rewrite_missing_comment(span, shape, context));
+    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 {
@@ -254,13 +254,7 @@ fn identify_comment(
         .collect::<Vec<_>>()
         .join("\n");
 
-    let first_group_str = try_opt!(rewrite_comment_inner(
-        &first_group,
-        block_style,
-        style,
-        shape,
-        config,
-    ));
+    let first_group_str = rewrite_comment_inner(&first_group, block_style, style, shape, config)?;
     if rest.is_empty() {
         Some(first_group_str)
     } else {
@@ -380,7 +374,7 @@ pub fn recover_missing_comment_in_span(
     context: &RewriteContext,
     used_width: usize,
 ) -> Option<String> {
-    let missing_comment = try_opt!(rewrite_missing_comment(span, shape, context));
+    let missing_comment = rewrite_missing_comment(span, shape, context)?;
     if missing_comment.is_empty() {
         Some(String::new())
     } else {
@@ -610,7 +604,7 @@ where
     type Item = (FullCodeCharKind, T::Item);
 
     fn next(&mut self) -> Option<(FullCodeCharKind, T::Item)> {
-        let item = try_opt!(self.base.next());
+        let item = self.base.next()?;
         let chr = item.get_char();
         self.status = match self.status {
             CharClassesStatus::LitString => match chr {
@@ -705,7 +699,7 @@ impl<'a> Iterator for UngroupedCommentCodeSlices<'a> {
     type Item = (CodeCharKind, usize, &'a str);
 
     fn next(&mut self) -> Option<Self::Item> {
-        let (kind, (start_idx, _)) = try_opt!(self.iter.next());
+        let (kind, (start_idx, _)) = self.iter.next()?;
         match kind {
             FullCodeCharKind::Normal => {
                 // Consume all the Normal code
@@ -886,14 +880,14 @@ impl<'a> Iterator for CommentReducer<'a> {
     type Item = char;
     fn next(&mut self) -> Option<Self::Item> {
         loop {
-            let mut c = try_opt!(self.iter.next());
+            let mut c = self.iter.next()?;
             if self.is_block && self.at_start_line {
                 while c.is_whitespace() {
-                    c = try_opt!(self.iter.next());
+                    c = self.iter.next()?;
                 }
                 // Ignore leading '*'
                 if c == '*' {
-                    c = try_opt!(self.iter.next());
+                    c = self.iter.next()?;
                 }
             } else if c == '\n' {
                 self.at_start_line = true;
diff --git a/src/expr.rs b/src/expr.rs
index 270087f122e..083aee5a225 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -75,7 +75,7 @@ pub fn format_expr(
         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 = try_opt!(callee.rewrite(context, shape));
+            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),
@@ -120,7 +120,7 @@ pub fn format_expr(
                         // Rewrite block without trying to put it in a single line.
                         rw
                     } else {
-                        let prefix = try_opt!(block_prefix(context, block, shape));
+                        let prefix = block_prefix(context, block, shape)?;
                         rewrite_block_with_visitor(context, &prefix, block, shape)
                     }
                 }
@@ -295,7 +295,7 @@ pub fn format_expr(
                 Some(format!(
                     "{}{}",
                     "do catch ",
-                    try_opt!(block.rewrite(context, Shape::legacy(budget, shape.indent)))
+                    block.rewrite(context, Shape::legacy(budget, shape.indent))?
                 ))
             }
         }
@@ -307,7 +307,7 @@ pub fn format_expr(
         })
         .and_then(|expr_str| {
             let attrs = outer_attributes(&expr.attrs);
-            let attrs_str = try_opt!(attrs.rewrite(context, shape));
+            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(),
@@ -338,10 +338,8 @@ where
         width: context.budget(lhs_overhead),
         ..shape
     };
-    let lhs_result = try_opt!(
-        lhs.rewrite(context, lhs_shape)
-            .map(|lhs_str| format!("{}{}", prefix, lhs_str))
-    );
+    let lhs_result = lhs.rewrite(context, lhs_shape)
+        .map(|lhs_str| format!("{}{}", prefix, lhs_str))?;
 
     // Try to the both lhs and rhs on the same line.
     let rhs_orig_result = shape
@@ -367,25 +365,25 @@ where
 
     // We have to use multiple lines.
     // Re-evaluate the rhs because we have more space now:
-    let mut rhs_shape = try_opt!(match context.config.control_style() {
+    let mut rhs_shape = match context.config.control_style() {
         Style::Legacy => shape
-            .sub_width(suffix.len() + prefix.len())
-            .map(|s| s.visual_indent(prefix.len())),
+            .sub_width(suffix.len() + prefix.len())?
+            .visual_indent(prefix.len()),
         Style::Rfc => {
             // 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)
+                .sub_width(rhs_overhead)?
         }
-    });
+    };
     let infix = match separator_place {
         SeparatorPlace::Back => infix.trim_right(),
         SeparatorPlace::Front => infix.trim_left(),
     };
     if separator_place == SeparatorPlace::Front {
-        rhs_shape = try_opt!(rhs_shape.offset_left(infix.len()));
+        rhs_shape = rhs_shape.offset_left(infix.len())?;
     }
-    let rhs_result = try_opt!(rhs.rewrite(context, rhs_shape));
+    let rhs_result = rhs.rewrite(context, rhs_shape)?;
     match separator_place {
         SeparatorPlace::Back => Some(format!(
             "{}{}\n{}{}{}",
@@ -423,18 +421,14 @@ where
     };
 
     let nested_shape = match context.config.array_layout() {
-        IndentStyle::Block => try_opt!(
-            shape
-                .block()
-                .block_indent(context.config.tab_spaces())
-                .with_max_width(context.config)
-                .sub_width(1)
-        ),
-        IndentStyle::Visual => try_opt!(
-            shape
-                .visual_indent(bracket_size)
-                .sub_width(bracket_size * 2)
-        ),
+        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(
@@ -507,7 +501,7 @@ where
         preserve_newline: false,
         config: context.config,
     };
-    let list_str = try_opt!(write_list(&items, &fmt));
+    let list_str = write_list(&items, &fmt)?;
 
     let result = if context.config.array_layout() == IndentStyle::Visual
         || tactic == DefinitiveListTactic::Horizontal
@@ -545,12 +539,12 @@ fn rewrite_closure_fn_decl(
     };
     // 4 = "|| {".len(), which is overconservative when the closure consists of
     // a single expression.
-    let nested_shape = try_opt!(try_opt!(shape.shrink_left(mover.len())).sub_width(4));
+    let nested_shape = shape.shrink_left(mover.len())?.sub_width(4)?;
 
     // 1 = |
     let argument_offset = nested_shape.indent + 1;
-    let arg_shape = try_opt!(nested_shape.offset_left(1)).visual_indent(0);
-    let ret_str = try_opt!(fn_decl.output.rewrite(context, arg_shape));
+    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,
@@ -576,7 +570,7 @@ fn rewrite_closure_fn_decl(
         horizontal_budget,
     );
     let arg_shape = match tactic {
-        DefinitiveListTactic::Horizontal => try_opt!(arg_shape.sub_width(ret_str.len() + 1)),
+        DefinitiveListTactic::Horizontal => arg_shape.sub_width(ret_str.len() + 1)?,
         _ => arg_shape,
     };
 
@@ -590,7 +584,7 @@ fn rewrite_closure_fn_decl(
         preserve_newline: true,
         config: context.config,
     };
-    let list_str = try_opt!(write_list(&item_vec, &fmt));
+    let list_str = write_list(&item_vec, &fmt)?;
     let mut prefix = format!("{}|{}|", mover, list_str);
     // 1 = space between `|...|` and body.
     let extra_offset = extra_offset(&prefix, shape) + 1;
@@ -625,16 +619,10 @@ fn rewrite_closure(
     context: &RewriteContext,
     shape: Shape,
 ) -> Option<String> {
-    let (prefix, extra_offset) = try_opt!(rewrite_closure_fn_decl(
-        capture,
-        fn_decl,
-        body,
-        span,
-        context,
-        shape,
-    ));
+    let (prefix, extra_offset) =
+        rewrite_closure_fn_decl(capture, fn_decl, body, span, context, shape)?;
     // 1 = space between `|...|` and body.
-    let body_shape = try_opt!(shape.offset_left(extra_offset));
+    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.
@@ -741,7 +729,7 @@ fn rewrite_closure_block(
     // The body of the closure is big enough to be block indented, that
     // means we must re-format.
     let block_shape = shape.block();
-    let block_str = try_opt!(block.rewrite(context, block_shape));
+    let block_str = block.rewrite(context, block_shape)?;
     Some(format!("{} {}", prefix, block_str))
 }
 
@@ -791,21 +779,21 @@ fn block_prefix(context: &RewriteContext, block: &ast::Block, shape: Shape) -> O
     Some(match block.rules {
         ast::BlockCheckMode::Unsafe(..) => {
             let snippet = context.snippet(block.span);
-            let open_pos = try_opt!(snippet.find_uncommented("{"));
+            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 = try_opt!(shape.width.checked_sub(9));
+                let budget = shape.width.checked_sub(9)?;
                 format!(
                     "unsafe {} ",
-                    try_opt!(rewrite_comment(
+                    rewrite_comment(
                         trimmed,
                         true,
                         Shape::legacy(budget, shape.indent + 7),
                         context.config,
-                    ))
+                    )?
                 )
             } else {
                 "unsafe ".to_owned()
@@ -823,7 +811,7 @@ fn rewrite_single_line_block(
 ) -> Option<String> {
     if is_simple_block(block, context.codemap) {
         let expr_shape = Shape::legacy(shape.width - prefix.len(), shape.indent);
-        let expr_str = try_opt!(block.stmts[0].rewrite(context, expr_shape));
+        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);
@@ -848,7 +836,7 @@ fn rewrite_block_with_visitor(
     match block.rules {
         ast::BlockCheckMode::Unsafe(..) => {
             let snippet = context.snippet(block.span);
-            let open_pos = try_opt!(snippet.find_uncommented("{"));
+            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(),
@@ -866,7 +854,7 @@ impl Rewrite for ast::Block {
             return rw;
         }
 
-        let prefix = try_opt!(block_prefix(context, self, shape));
+        let prefix = block_prefix(context, self, shape)?;
 
         let result = rewrite_block_with_visitor(context, &prefix, self, shape);
         if let Some(ref result_str) = result {
@@ -894,7 +882,7 @@ impl Rewrite for ast::Stmt {
                     ""
                 };
 
-                let shape = try_opt!(shape.sub_width(suffix.len()));
+                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,
@@ -909,8 +897,8 @@ fn rewrite_cond(context: &RewriteContext, expr: &ast::Expr, shape: Shape) -> Opt
         ast::ExprKind::Match(ref cond, _) => {
             // `match `cond` {`
             let cond_shape = match context.config.control_style() {
-                Style::Legacy => try_opt!(shape.shrink_left(6).and_then(|s| s.sub_width(2))),
-                Style::Rfc => try_opt!(shape.offset_left(8)),
+                Style::Legacy => shape.shrink_left(6).and_then(|s| s.sub_width(2))?,
+                Style::Rfc => shape.offset_left(8)?,
             };
             cond.rewrite(context, cond_shape)
         }
@@ -1084,7 +1072,7 @@ impl<'a> ControlFlow<'a> {
         width: usize,
     ) -> Option<String> {
         assert!(self.allow_single_line);
-        let else_block = try_opt!(self.else_block);
+        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 {
@@ -1095,14 +1083,13 @@ impl<'a> ControlFlow<'a> {
                 return None;
             }
 
-            let new_width = try_opt!(width.checked_sub(pat_expr_str.len() + fixed_cost));
+            let new_width = width.checked_sub(pat_expr_str.len() + fixed_cost)?;
             let expr = &self.block.stmts[0];
-            let if_str = try_opt!(expr.rewrite(context, Shape::legacy(new_width, Indent::empty())));
+            let if_str = expr.rewrite(context, Shape::legacy(new_width, Indent::empty()))?;
 
-            let new_width = try_opt!(new_width.checked_sub(if_str.len()));
+            let new_width = new_width.checked_sub(if_str.len())?;
             let else_expr = &else_node.stmts[0];
-            let else_str =
-                try_opt!(else_expr.rewrite(context, Shape::legacy(new_width, Indent::empty())));
+            let else_str = else_expr.rewrite(context, Shape::legacy(new_width, Indent::empty()))?;
 
             if if_str.contains('\n') || else_str.contains('\n') {
                 return None;
@@ -1146,7 +1133,7 @@ impl<'a> ControlFlow<'a> {
         let constr_shape = if self.nested_if {
             // We are part of an if-elseif-else chain. Our constraints are tightened.
             // 7 = "} else " .len()
-            try_opt!(fresh_shape.offset_left(7))
+            fresh_shape.offset_left(7)?
         } else {
             fresh_shape
         };
@@ -1158,10 +1145,10 @@ impl<'a> ControlFlow<'a> {
         let pat_expr_string = match self.cond {
             Some(cond) => {
                 let cond_shape = match context.config.control_style() {
-                    Style::Legacy => try_opt!(constr_shape.shrink_left(offset)),
-                    Style::Rfc => try_opt!(constr_shape.offset_left(offset)),
+                    Style::Legacy => constr_shape.shrink_left(offset)?,
+                    Style::Rfc => constr_shape.offset_left(offset)?,
                 };
-                try_opt!(rewrite_pat_expr(
+                rewrite_pat_expr(
                     context,
                     self.pat,
                     cond,
@@ -1169,7 +1156,7 @@ impl<'a> ControlFlow<'a> {
                     self.connector,
                     self.keyword,
                     cond_shape,
-                ))
+                )?
             }
             None => String::new(),
         };
@@ -1271,7 +1258,7 @@ impl<'a> Rewrite for ControlFlow<'a> {
 
         let alt_block_sep =
             String::from("\n") + &shape.indent.block_only().to_string(context.config);
-        let (cond_str, used_width) = try_opt!(self.rewrite_cond(context, shape, &alt_block_sep));
+        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);
@@ -1291,12 +1278,7 @@ impl<'a> Rewrite for ControlFlow<'a> {
         };
         let mut block_context = context.clone();
         block_context.is_if_else_block = self.else_block.is_some();
-        let block_str = try_opt!(rewrite_block_with_visitor(
-            &block_context,
-            "",
-            self.block,
-            block_shape,
-        ));
+        let block_str = rewrite_block_with_visitor(&block_context, "", self.block, block_shape)?;
 
         let mut result = format!("{}{}", cond_str, block_str);
 
@@ -1369,17 +1351,15 @@ impl<'a> Rewrite for ControlFlow<'a> {
                 ControlBraceStyle::AlwaysNextLine if last_in_chain => &*alt_block_sep,
                 _ => " ",
             };
-            try_opt!(
-                write!(
-                    &mut result,
-                    "{}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)
-                ).ok()
-            );
-            result.push_str(&try_opt!(rewrite));
+            write!(
+                &mut result,
+                "{}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)
+            ).ok()?;
+            result.push_str(&rewrite?);
         }
 
         Some(result)
@@ -1476,17 +1456,17 @@ fn rewrite_match(
 
     // Do not take the rhs overhead from the upper expressions into account
     // when rewriting match condition.
-    let new_width = try_opt!(context.config.max_width().checked_sub(shape.used_width()));
+    let new_width = context.config.max_width().checked_sub(shape.used_width())?;
     let cond_shape = Shape {
         width: new_width,
         ..shape
     };
     // 6 = `match `
     let cond_shape = match context.config.control_style() {
-        Style::Legacy => try_opt!(cond_shape.shrink_left(6)),
-        Style::Rfc => try_opt!(cond_shape.offset_left(6)),
+        Style::Legacy => cond_shape.shrink_left(6)?,
+        Style::Rfc => cond_shape.offset_left(6)?,
     };
-    let cond_str = try_opt!(cond.rewrite(context, cond_shape));
+    let cond_str = cond.rewrite(context, cond_shape)?;
     let alt_block_sep = String::from("\n") + &shape.indent.block_only().to_string(context.config);
     let block_sep = match context.config.control_brace_style() {
         ControlBraceStyle::AlwaysNextLine => &alt_block_sep,
@@ -1505,11 +1485,9 @@ fn rewrite_match(
     let inner_attrs_str = if inner_attrs.is_empty() {
         String::new()
     } else {
-        try_opt!(
-            inner_attrs
-                .rewrite(context, shape)
-                .map(|s| format!("{}{}\n", nested_indent_str, s))
-        )
+        inner_attrs
+            .rewrite(context, shape)
+            .map(|s| format!("{}{}\n", nested_indent_str, s))?
     };
 
     let open_brace_pos = if inner_attrs.is_empty() {
@@ -1532,13 +1510,7 @@ fn rewrite_match(
         block_sep,
         inner_attrs_str,
         arm_indent_str,
-        try_opt!(rewrite_match_arms(
-            context,
-            arms,
-            shape,
-            span,
-            open_brace_pos,
-        )),
+        rewrite_match_arms(context, arms, shape, span, open_brace_pos,)?,
         shape.indent.to_string(context.config),
     ))
 }
@@ -1626,12 +1598,12 @@ fn rewrite_match_arm(
                 arm.attrs[arm.attrs.len() - 1].span.hi(),
                 arm.pats[0].span.lo(),
             ),
-            try_opt!(arm.attrs.rewrite(context, shape)),
+            arm.attrs.rewrite(context, shape)?,
         )
     } else {
         (mk_sp(arm.span().lo(), arm.span().lo()), String::new())
     };
-    let pats_str = try_opt!(
+    let pats_str =
         rewrite_match_pattern(context, &arm.pats, &arm.guard, shape).and_then(|pats_str| {
             combine_strs_with_missing_comments(
                 context,
@@ -1641,8 +1613,7 @@ fn rewrite_match_arm(
                 shape,
                 false,
             )
-        })
-    );
+        })?;
     rewrite_match_body(
         context,
         &arm.body,
@@ -1661,13 +1632,11 @@ fn rewrite_match_pattern(
 ) -> Option<String> {
     // Patterns
     // 5 = ` => {`
-    let pat_shape = try_opt!(shape.sub_width(5));
+    let pat_shape = shape.sub_width(5)?;
 
-    let pat_strs = try_opt!(
-        pats.iter()
-            .map(|p| p.rewrite(context, pat_shape))
-            .collect::<Option<Vec<_>>>()
-    );
+    let pat_strs = pats.iter()
+        .map(|p| p.rewrite(context, pat_shape))
+        .collect::<Option<Vec<_>>>()?;
 
     let items: Vec<_> = pat_strs.into_iter().map(ListItem::from_str).collect();
     let tactic = definitive_tactic(
@@ -1686,15 +1655,10 @@ fn rewrite_match_pattern(
         preserve_newline: false,
         config: context.config,
     };
-    let pats_str = try_opt!(write_list(&items, &fmt));
+    let pats_str = write_list(&items, &fmt)?;
 
     // Guard
-    let guard_str = try_opt!(rewrite_guard(
-        context,
-        guard,
-        shape,
-        trimmed_last_line_width(&pats_str),
-    ));
+    let guard_str = rewrite_guard(context, guard, shape, trimmed_last_line_width(&pats_str))?;
 
     Some(format!("{}{}", pats_str, guard_str))
 }
@@ -1910,9 +1874,8 @@ fn rewrite_pat_expr(
         } else {
             format!("{} ", matcher)
         };
-        let pat_shape =
-            try_opt!(try_opt!(shape.offset_left(matcher.len())).sub_width(connector.len()));
-        let pat_string = try_opt!(pat.rewrite(context, pat_shape));
+        let pat_shape = 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, shape);
     }
@@ -2047,19 +2010,19 @@ where
         1
     };
     let used_width = extra_offset(callee_str, shape);
-    let one_line_width = try_opt!(shape.width.checked_sub(used_width + 2 * paren_overhead));
+    let one_line_width = shape.width.checked_sub(used_width + 2 * paren_overhead)?;
 
-    let nested_shape = try_opt!(shape_from_fn_call_style(
+    let nested_shape = shape_from_fn_call_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) = try_opt!(rewrite_call_args(
+    let (extendable, list_str) = rewrite_call_args(
         context,
         args,
         args_span,
@@ -2067,7 +2030,7 @@ where
         one_line_width,
         args_max_width,
         force_trailing_comma,
-    ));
+    )?;
 
     if !context.use_block_indent() && need_block_indent(&list_str, nested_shape) && !extendable {
         let mut new_context = context.clone();
@@ -2083,7 +2046,7 @@ where
         );
     }
 
-    let args_shape = try_opt!(shape.sub_width(last_line_width(callee_str)));
+    let args_shape = shape.sub_width(last_line_width(callee_str))?;
     Some(format!(
         "{}{}",
         callee_str,
@@ -2242,7 +2205,7 @@ fn last_arg_shape(
         shape.block().indent
     };
     Some(Shape {
-        width: try_opt!(max_width.checked_sub(overhead)),
+        width: max_width.checked_sub(overhead)?,
         indent: arg_indent,
         offset: 0,
     })
@@ -2262,19 +2225,13 @@ fn rewrite_last_closure(
             }
             _ => body,
         };
-        let (prefix, extra_offset) = try_opt!(rewrite_closure_fn_decl(
-            capture,
-            fn_decl,
-            body,
-            expr.span,
-            context,
-            shape,
-        ));
+        let (prefix, extra_offset) =
+            rewrite_closure_fn_decl(capture, 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 = try_opt!(shape.offset_left(extra_offset));
+        let body_shape = shape.offset_left(extra_offset)?;
         // 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)
@@ -2414,11 +2371,9 @@ fn rewrite_paren(context: &RewriteContext, subexpr: &ast::Expr, shape: Shape) ->
     debug!("rewrite_paren, shape: {:?}", shape);
     let total_paren_overhead = paren_overhead(context);
     let paren_overhead = total_paren_overhead / 2;
-    let sub_shape = try_opt!(
-        shape
-            .offset_left(paren_overhead)
-            .and_then(|s| s.sub_width(paren_overhead))
-    );
+    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() && !s.is_empty() {
         format!("( {} )", s)
@@ -2426,7 +2381,7 @@ fn rewrite_paren(context: &RewriteContext, subexpr: &ast::Expr, shape: Shape) ->
         format!("({})", s)
     };
 
-    let subexpr_str = try_opt!(subexpr.rewrite(context, sub_shape));
+    let subexpr_str = subexpr.rewrite(context, sub_shape)?;
     debug!("rewrite_paren, subexpr_str: `{:?}`", subexpr_str);
 
     if subexpr_str.contains('\n')
@@ -2444,7 +2399,7 @@ fn rewrite_index(
     context: &RewriteContext,
     shape: Shape,
 ) -> Option<String> {
-    let expr_str = try_opt!(expr.rewrite(context, shape));
+    let expr_str = expr.rewrite(context, shape)?;
 
     let (lbr, rbr) = if context.config.spaces_within_square_brackets() {
         ("[ ", " ]")
@@ -2473,8 +2428,8 @@ fn rewrite_index(
 
     // 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 = try_opt!(Shape::indented(indent, context.config).offset_left(lbr.len()));
-    let index_shape = try_opt!(index_shape.sub_width(rbr.len() + rhs_overhead));
+    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!(
@@ -2522,34 +2477,28 @@ fn rewrite_struct_lit<'a>(
     }
 
     // 2 = " {".len()
-    let path_shape = try_opt!(shape.sub_width(2));
-    let path_str = try_opt!(rewrite_path(
-        context,
-        PathContext::Expr,
-        None,
-        path,
-        path_shape,
-    ));
+    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) = try_opt!(struct_lit_shape(shape, context, path_str.len() + 3, 2));
+    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
     {
-        try_opt!(rewrite_with_alignment(
+        rewrite_with_alignment(
             fields,
             context,
             shape,
             mk_sp(body_lo, span.hi()),
             one_line_width,
-        ))
+        )?
     } else {
         let field_iter = fields
             .into_iter()
@@ -2572,11 +2521,11 @@ fn rewrite_struct_lit<'a>(
         let rewrite = |item: &StructLitField| match *item {
             StructLitField::Regular(field) => {
                 // The 1 taken from the v_budget is for the comma.
-                rewrite_field(context, field, try_opt!(v_shape.sub_width(1)), 0)
+                rewrite_field(context, field, v_shape.sub_width(1)?, 0)
             }
             StructLitField::Base(expr) => {
                 // 2 = ..
-                expr.rewrite(context, try_opt!(v_shape.offset_left(2)))
+                expr.rewrite(context, v_shape.offset_left(2)?)
                     .map(|s| format!("..{}", s))
             }
         };
@@ -2598,7 +2547,7 @@ fn rewrite_struct_lit<'a>(
         let nested_shape = shape_for_tactic(tactic, h_shape, v_shape);
         let fmt = struct_lit_formatting(nested_shape, tactic, context, base.is_some());
 
-        try_opt!(write_list(&item_vec, &fmt))
+        write_list(&item_vec, &fmt)?
     };
 
     let fields_str = wrap_struct_field(context, &fields_str, shape, v_shape, one_line_width);
@@ -2657,10 +2606,10 @@ pub fn rewrite_field(
             separator.push(' ');
         }
         let overhead = name.len() + separator.len();
-        let expr_shape = try_opt!(shape.offset_left(overhead));
+        let expr_shape = shape.offset_left(overhead)?;
         let expr = field.expr.rewrite(context, expr_shape);
 
-        let mut attrs_str = try_opt!(field.attrs.rewrite(context, shape));
+        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)));
         };
@@ -2718,7 +2667,7 @@ where
     debug!("rewrite_tuple_in_visual_indent_style {:?}", shape);
     if items.len() == 1 {
         // 3 = "(" + ",)"
-        let nested_shape = try_opt!(shape.sub_width(3)).visual_indent(1);
+        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() {
                 format!("( {}, )", s)
@@ -2729,7 +2678,7 @@ where
     }
 
     let list_lo = context.codemap.span_after(span, "(");
-    let nested_shape = try_opt!(shape.sub_width(2)).visual_indent(1);
+    let nested_shape = shape.sub_width(2)?.visual_indent(1);
     let items = itemize_list(
         context.codemap,
         items,
@@ -2758,7 +2707,7 @@ where
         preserve_newline: false,
         config: context.config,
     };
-    let list_str = try_opt!(write_list(&item_vec, &fmt));
+    let list_str = write_list(&item_vec, &fmt)?;
 
     if context.config.spaces_within_parens() && !list_str.is_empty() {
         Some(format!("( {} )", list_str))
@@ -2805,7 +2754,7 @@ pub fn rewrite_unary_prefix<R: Rewrite>(
     shape: Shape,
 ) -> Option<String> {
     rewrite
-        .rewrite(context, try_opt!(shape.offset_left(prefix.len())))
+        .rewrite(context, shape.offset_left(prefix.len())?)
         .map(|r| format!("{}{}", prefix, r))
 }
 
@@ -2818,7 +2767,7 @@ pub fn rewrite_unary_suffix<R: Rewrite>(
     shape: Shape,
 ) -> Option<String> {
     rewrite
-        .rewrite(context, try_opt!(shape.sub_width(suffix.len())))
+        .rewrite(context, shape.sub_width(suffix.len())?)
         .map(|mut r| {
             r.push_str(suffix);
             r
@@ -2853,12 +2802,8 @@ fn rewrite_assignment(
     };
 
     // 1 = space between lhs and operator.
-    let lhs_shape = try_opt!(shape.sub_width(operator_str.len() + 1));
-    let lhs_str = format!(
-        "{} {}",
-        try_opt!(lhs.rewrite(context, lhs_shape)),
-        operator_str
-    );
+    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)
 }
@@ -2878,13 +2823,8 @@ pub fn rewrite_assign_rhs<S: Into<String>>(
         0
     };
     // 1 = space between operator and rhs.
-    let orig_shape = try_opt!(shape.offset_left(last_line_width + 1));
-    let rhs = try_opt!(choose_rhs(
-        context,
-        ex,
-        orig_shape,
-        ex.rewrite(context, orig_shape)
-    ));
+    let orig_shape = shape.offset_left(last_line_width + 1)?;
+    let rhs = choose_rhs(context, ex, orig_shape, ex.rewrite(context, orig_shape))?;
     Some(lhs + &rhs)
 }
 
@@ -2901,12 +2841,10 @@ fn choose_rhs(
         _ => {
             // Expression did not fit on the same line as the identifier.
             // Try splitting the line and see if that works better.
-            let new_shape = try_opt!(
-                Shape::indented(
-                    shape.block().indent.block_indent(context.config),
-                    context.config,
-                ).sub_width(shape.rhs_overhead(context.config))
-            );
+            let new_shape = Shape::indented(
+                shape.block().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);
 
diff --git a/src/imports.rs b/src/imports.rs
index 4331ea84bc5..68c3ec32897 100644
--- a/src/imports.rs
+++ b/src/imports.rs
@@ -140,21 +140,9 @@ fn rewrite_view_path_prefix(
             span: path.span,
             segments: path.segments[..path.segments.len() - 1].to_owned(),
         };
-        try_opt!(rewrite_path(
-            context,
-            PathContext::Import,
-            None,
-            path,
-            shape,
-        ))
+        rewrite_path(context, PathContext::Import, None, path, shape)?
     } else {
-        try_opt!(rewrite_path(
-            context,
-            PathContext::Import,
-            None,
-            path,
-            shape,
-        ))
+        rewrite_path(context, PathContext::Import, None, path, shape)?
     };
     Some(path_str)
 }
@@ -167,15 +155,15 @@ impl Rewrite for ast::ViewPath {
             }
             ast::ViewPath_::ViewPathGlob(ref path) => {
                 // 4 = "::*".len()
-                let prefix_shape = try_opt!(shape.sub_width(3));
-                let path_str = try_opt!(rewrite_view_path_prefix(path, context, prefix_shape));
+                let prefix_shape = shape.sub_width(3)?;
+                let path_str = rewrite_view_path_prefix(path, context, prefix_shape)?;
                 Some(format!("{}::*", path_str))
             }
             ast::ViewPath_::ViewPathSimple(ident, ref path) => {
                 let ident_str = ident.to_string();
                 // 4 = " as ".len()
-                let prefix_shape = try_opt!(shape.sub_width(ident_str.len() + 4));
-                let path_str = try_opt!(rewrite_view_path_prefix(path, context, prefix_shape));
+                let prefix_shape = shape.sub_width(ident_str.len() + 4)?;
+                let path_str = rewrite_view_path_prefix(path, context, prefix_shape)?;
 
                 Some(if path.segments.last().unwrap().identifier == ident {
                     path_str
@@ -228,7 +216,7 @@ fn rewrite_imports(
         |item| item.span().lo(),
         |item| item.span().hi(),
         |item| {
-            let attrs_str = try_opt!(item.attrs.rewrite(context, shape));
+            let attrs_str = item.attrs.rewrite(context, shape)?;
 
             let missed_span = if item.attrs.is_empty() {
                 mk_sp(item.span.lo(), item.span.lo())
@@ -238,9 +226,9 @@ fn rewrite_imports(
 
             let item_str = match item.node {
                 ast::ItemKind::Use(ref vp) => {
-                    try_opt!(rewrite_import(context, &item.vis, vp, &item.attrs, shape))
+                    rewrite_import(context, &item.vis, vp, &item.attrs, shape)?
                 }
-                ast::ItemKind::ExternCrate(..) => try_opt!(rewrite_extern_crate(context, item)),
+                ast::ItemKind::ExternCrate(..) => rewrite_extern_crate(context, item)?,
                 _ => return None,
             };
 
@@ -428,13 +416,7 @@ fn rewrite_use_list(
     context: &RewriteContext,
 ) -> Option<String> {
     // Returns a different option to distinguish `::foo` and `foo`
-    let path_str = try_opt!(rewrite_path(
-        context,
-        PathContext::Import,
-        None,
-        path,
-        shape,
-    ));
+    let path_str = rewrite_path(context, PathContext::Import, None, path, shape)?;
 
     match path_list.len() {
         0 => {
@@ -521,7 +503,7 @@ fn rewrite_use_list(
         preserve_newline: true,
         config: context.config,
     };
-    let list_str = try_opt!(write_list(&items[first_index..], &fmt));
+    let list_str = write_list(&items[first_index..], &fmt)?;
 
     let result = if list_str.contains('\n') && context.config.imports_indent() == IndentStyle::Block
     {
diff --git a/src/items.rs b/src/items.rs
index 8678e40ad22..e2580bea8de 100644
--- a/src/items.rs
+++ b/src/items.rs
@@ -62,11 +62,11 @@ impl Rewrite for ast::Local {
             return None;
         }
 
-        let attrs_str = try_opt!(self.attrs.rewrite(context, shape));
+        let attrs_str = self.attrs.rewrite(context, shape)?;
         let mut result = if attrs_str.is_empty() {
             "let ".to_owned()
         } else {
-            try_opt!(combine_strs_with_missing_comments(
+            combine_strs_with_missing_comments(
                 context,
                 &attrs_str,
                 "let ",
@@ -76,14 +76,14 @@ impl Rewrite for ast::Local {
                 ),
                 shape,
                 false,
-            ))
+            )?
         };
 
         // 4 = "let ".len()
-        let pat_shape = try_opt!(shape.offset_left(4));
+        let pat_shape = shape.offset_left(4)?;
         // 1 = ;
-        let pat_shape = try_opt!(pat_shape.sub_width(1));
-        let pat_str = try_opt!(self.pat.rewrite(context, pat_shape));
+        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.
@@ -94,8 +94,8 @@ impl Rewrite for ast::Local {
                 let separator = type_annotation_separator(context.config);
                 let indent = shape.indent + last_line_width(&result) + separator.len();
                 // 1 = ;
-                let budget = try_opt!(shape.width.checked_sub(indent.width() + 1));
-                let rewrite = try_opt!(ty.rewrite(context, Shape::legacy(budget, indent)));
+                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);
@@ -112,9 +112,9 @@ impl Rewrite for ast::Local {
 
         if let Some(ref ex) = self.init {
             // 1 = trailing semicolon;
-            let nested_shape = try_opt!(shape.sub_width(1));
+            let nested_shape = shape.sub_width(1)?;
 
-            result = try_opt!(rewrite_assign_rhs(context, result, ex, nested_shape));
+            result = rewrite_assign_rhs(context, result, ex, nested_shape)?;
         }
 
         result.push(';');
@@ -306,15 +306,8 @@ impl<'a> FmtVisitor<'a> {
         let mut newline_brace =
             newline_for_brace(self.config, &fn_sig.generics.where_clause, has_body);
 
-        let (mut result, force_newline_brace) = try_opt!(rewrite_fn_base(
-            &context,
-            indent,
-            ident,
-            fn_sig,
-            span,
-            newline_brace,
-            true,
-        ));
+        let (mut result, force_newline_brace) =
+            rewrite_fn_base(&context, indent, ident, fn_sig, span, newline_brace, true)?;
 
         if self.config.fn_brace_style() == BraceStyle::AlwaysNextLine || force_newline_brace {
             newline_brace = true;
@@ -351,7 +344,7 @@ impl<'a> FmtVisitor<'a> {
         let span = mk_sp(span.lo(), span.hi() - BytePos(1));
         let context = self.get_context();
 
-        let (mut result, _) = try_opt!(rewrite_fn_base(
+        let (mut result, _) = rewrite_fn_base(
             &context,
             indent,
             ident,
@@ -359,7 +352,7 @@ impl<'a> FmtVisitor<'a> {
             span,
             false,
             false,
-        ));
+        )?;
 
         // Re-attach semicolon
         result.push(';');
@@ -503,7 +496,7 @@ impl<'a> FmtVisitor<'a> {
             config: self.config,
         };
 
-        let list = try_opt!(write_list(&items.collect::<Vec<_>>(), &fmt));
+        let list = write_list(&items.collect::<Vec<_>>(), &fmt)?;
         result.push_str(&list);
         result.push('\n');
         Some(result)
@@ -520,7 +513,7 @@ impl<'a> FmtVisitor<'a> {
         let context = self.get_context();
         let indent = self.block_indent;
         let shape = self.shape();
-        let attrs_str = try_opt!(field.node.attrs.rewrite(&context, shape));
+        let attrs_str = field.node.attrs.rewrite(&context, shape)?;
         let lo = field
             .node
             .attrs
@@ -531,7 +524,7 @@ impl<'a> FmtVisitor<'a> {
         let variant_body = match field.node.data {
             ast::VariantData::Tuple(..) | ast::VariantData::Struct(..) => {
                 // FIXME: Should limit the width, as we have a trailing comma
-                try_opt!(format_struct(
+                format_struct(
                     &context,
                     "",
                     field.node.name,
@@ -541,7 +534,7 @@ impl<'a> FmtVisitor<'a> {
                     field.span,
                     indent,
                     Some(self.config.struct_variant_width()),
-                ))
+                )?
             }
             ast::VariantData::Unit(..) => if let Some(ref expr) = field.node.disr_expr {
                 let one_line_width =
@@ -586,7 +579,7 @@ pub fn format_impl(
 ) -> 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 = try_opt!(format_impl_ref_and_type(context, item, offset));
+        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);
@@ -597,7 +590,7 @@ pub fn format_impl(
             context.budget(last_line_width(&result))
         };
         let option = WhereClauseOption::snuggled(&ref_and_type);
-        let where_clause_str = try_opt!(rewrite_where_clause(
+        let where_clause_str = rewrite_where_clause(
             context,
             &generics.where_clause,
             context.config.item_brace_style(),
@@ -607,7 +600,7 @@ pub fn format_impl(
             where_span_end,
             self_ty.span.hi(),
             option,
-        ));
+        )?;
 
         // If there is no where clause, we may have missing comments between the trait name and
         // the opening brace.
@@ -627,13 +620,7 @@ pub fn format_impl(
             }
         }
 
-        if try_opt!(is_impl_single_line(
-            context,
-            items,
-            &result,
-            &where_clause_str,
-            item,
-        )) {
+        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));
@@ -665,7 +652,7 @@ pub fn format_impl(
         result.push('{');
 
         let snippet = context.snippet(item.span);
-        let open_pos = try_opt!(snippet.find_uncommented("{")) + 1;
+        let open_pos = snippet.find_uncommented("{")? + 1;
 
         if !items.is_empty() || contains_comment(&snippet[open_pos..]) {
             let mut visitor = FmtVisitor::from_codemap(context.parse_session, context.config);
@@ -708,7 +695,7 @@ fn is_impl_single_line(
     item: &ast::Item,
 ) -> Option<bool> {
     let snippet = context.snippet(item.span);
-    let open_pos = try_opt!(snippet.find_uncommented("{")) + 1;
+    let open_pos = snippet.find_uncommented("{")? + 1;
 
     Some(
         context.config.impl_empty_single_line() && items.is_empty() && !result.contains('\n')
@@ -744,19 +731,14 @@ fn format_impl_ref_and_type(
             Some(ref tr) => tr.path.span.lo(),
             None => self_ty.span.lo(),
         };
-        let shape = try_opt!(generics_shape_from_config(
+        let shape = generics_shape_from_config(
             context.config,
             Shape::indented(offset + last_line_width(&result), context.config),
             0,
-        ));
-        let one_line_budget = try_opt!(shape.width.checked_sub(last_line_width(&result) + 2));
-        let generics_str = try_opt!(rewrite_generics_inner(
-            context,
-            generics,
-            shape,
-            one_line_budget,
-            mk_sp(lo, hi),
-        ));
+        )?;
+        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 {
             "!"
@@ -777,14 +759,9 @@ fn format_impl_ref_and_type(
             ) {
                 result.push_str(&trait_ref_str);
             } else {
-                let generics_str = try_opt!(rewrite_generics_inner(
-                    context,
-                    generics,
-                    shape,
-                    0,
-                    mk_sp(lo, hi),
-                ));
-                result.push_str(&try_opt!(rewrite_trait_ref(
+                let generics_str =
+                    rewrite_generics_inner(context, generics, shape, 0, mk_sp(lo, hi))?;
+                result.push_str(&rewrite_trait_ref(
                     context,
                     trait_ref,
                     offset,
@@ -792,7 +769,7 @@ fn format_impl_ref_and_type(
                     false,
                     polarity_str,
                     result_len,
-                )));
+                )?);
             }
         } else {
             result.push_str(&generics_str);
@@ -839,9 +816,8 @@ fn format_impl_ref_and_type(
             Style::Legacy => new_line_offset + trait_ref_overhead,
             Style::Rfc => new_line_offset,
         };
-        result.push_str(&*try_opt!(
-            self_ty.rewrite(context, Shape::legacy(budget, type_offset))
-        ));
+        result.push_str(&*self_ty
+            .rewrite(context, Shape::legacy(budget, type_offset))?);
         Some(result)
     } else {
         unreachable!();
@@ -874,7 +850,7 @@ fn rewrite_trait_ref(
     if !retry {
         let offset = offset.block_indent(context.config);
         let shape = Shape::indented(offset, context.config);
-        let trait_ref_str = try_opt!(trait_ref.rewrite(context, shape));
+        let trait_ref_str = trait_ref.rewrite(context, shape)?;
         Some(format!(
             "{}\n{}{}{}",
             generics_str,
@@ -941,19 +917,15 @@ pub fn format_trait(context: &RewriteContext, item: &ast::Item, offset: Indent)
         let body_lo = context.codemap.span_after(item.span, "{");
 
         let shape = Shape::indented(offset + last_line_width(&result), context.config);
-        let generics_str = try_opt!(rewrite_generics(
-            context,
-            generics,
-            shape,
-            mk_sp(item.span.lo(), body_lo),
-        ));
+        let generics_str =
+            rewrite_generics(context, generics, shape, mk_sp(item.span.lo(), body_lo))?;
         result.push_str(&generics_str);
 
-        let trait_bound_str = try_opt!(rewrite_trait_bounds(
+        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()
@@ -985,7 +957,7 @@ pub fn format_trait(context: &RewriteContext, item: &ast::Item, offset: Indent)
             type_param_bounds[type_param_bounds.len() - 1].span().hi()
         };
         let option = WhereClauseOption::snuggled(&generics_str);
-        let where_clause_str = try_opt!(rewrite_where_clause(
+        let where_clause_str = rewrite_where_clause(
             context,
             &generics.where_clause,
             context.config.item_brace_style(),
@@ -995,7 +967,7 @@ pub fn format_trait(context: &RewriteContext, item: &ast::Item, offset: Indent)
             None,
             pos_before_where,
             option,
-        ));
+        )?;
         // If the where clause cannot fit on the same line,
         // put the where clause on a new line
         if !where_clause_str.contains('\n')
@@ -1053,7 +1025,7 @@ pub fn format_trait(context: &RewriteContext, item: &ast::Item, offset: Indent)
         result.push('{');
 
         let snippet = context.snippet(item.span);
-        let open_pos = try_opt!(snippet.find_uncommented("{")) + 1;
+        let open_pos = snippet.find_uncommented("{")? + 1;
 
         if !trait_items.is_empty() || contains_comment(&snippet[open_pos..]) {
             let mut visitor = FmtVisitor::from_codemap(context.parse_session, context.config);
@@ -1108,7 +1080,7 @@ pub fn format_struct_struct(
     let body_lo = context.codemap.span_after(span, "{");
 
     let generics_str = match generics {
-        Some(g) => try_opt!(format_generics(
+        Some(g) => format_generics(
             context,
             g,
             "{",
@@ -1118,7 +1090,7 @@ pub fn format_struct_struct(
             offset,
             mk_sp(span.lo(), body_lo),
             last_line_width(&result),
-        )),
+        )?,
         None => {
             // 3 = ` {}`, 2 = ` {`.
             let overhead = if fields.is_empty() { 3 } else { 2 };
@@ -1166,13 +1138,13 @@ pub fn format_struct_struct(
     let one_line_budget =
         one_line_width.map_or(0, |one_line_width| min(one_line_width, one_line_budget));
 
-    let items_str = try_opt!(rewrite_with_alignment(
+    let items_str = rewrite_with_alignment(
         fields,
         context,
         Shape::indented(offset, context.config),
         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))
@@ -1228,12 +1200,12 @@ fn format_tuple_struct(
             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 = try_opt!(rewrite_generics(context, generics, shape, g_span));
+            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);
-            try_opt!(rewrite_where_clause(
+            rewrite_where_clause(
                 context,
                 &generics.where_clause,
                 context.config.item_brace_style(),
@@ -1243,7 +1215,7 @@ fn format_tuple_struct(
                 None,
                 body_hi,
                 option,
-            ))
+            )?
         }
         None => "".to_owned(),
     };
@@ -1271,7 +1243,7 @@ fn format_tuple_struct(
         result.push(')');
     } else {
         // 3 = `();`
-        let body = try_opt!(rewrite_call_inner(
+        let body = rewrite_call_inner(
             context,
             "",
             &fields.iter().map(|field| field).collect::<Vec<_>>()[..],
@@ -1279,7 +1251,7 @@ fn format_tuple_struct(
             Shape::legacy(context.budget(last_line_width(&result) + 3), offset),
             context.config.fn_call_width(),
             false,
-        ));
+        )?;
         result.push_str(&body);
     }
 
@@ -1315,14 +1287,14 @@ pub fn rewrite_type_alias(
     result.push_str(&ident.to_string());
 
     // 2 = `= `
-    let shape = try_opt!(Shape::indented(indent + result.len(), context.config).sub_width(2));
+    let shape = Shape::indented(indent + result.len(), context.config).sub_width(2)?;
     let g_span = mk_sp(context.codemap.span_after(span, "type"), ty.span.lo());
-    let generics_str = try_opt!(rewrite_generics(context, generics, shape, g_span));
+    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::snuggled(&result);
-    let where_clause_str = try_opt!(rewrite_where_clause(
+    let where_clause_str = rewrite_where_clause(
         context,
         &generics.where_clause,
         context.config.item_brace_style(),
@@ -1332,7 +1304,7 @@ pub fn rewrite_type_alias(
         Some(span.hi()),
         generics.span.hi(),
         option,
-    ));
+    )?;
     result.push_str(&where_clause_str);
     if where_clause_str.is_empty() {
         result.push_str(" = ");
@@ -1346,20 +1318,18 @@ pub fn rewrite_type_alias(
     let budget = context.budget(indent.width() + line_width + ";".len());
     let type_indent = indent + line_width;
     // Try to fit the type on the same line
-    let ty_str = try_opt!(
-        ty.rewrite(context, Shape::legacy(budget, type_indent))
-            .or_else(|| {
-                // The line was too short, try to put the type on the next line
-
-                // Remove the space after '='
-                result.pop();
-                let type_indent = indent.block_indent(context.config);
-                result.push('\n');
-                result.push_str(&type_indent.to_string(context.config));
-                let budget = context.budget(type_indent.width() + ";".len());
-                ty.rewrite(context, Shape::legacy(budget, type_indent))
-            })
-    );
+    let ty_str = ty.rewrite(context, Shape::legacy(budget, type_indent))
+        .or_else(|| {
+            // The line was too short, try to put the type on the next line
+
+            // Remove the space after '='
+            result.pop();
+            let type_indent = indent.block_indent(context.config);
+            result.push('\n');
+            result.push_str(&type_indent.to_string(context.config));
+            let budget = context.budget(type_indent.width() + ";".len());
+            ty.rewrite(context, Shape::legacy(budget, type_indent))
+        })?;
     result.push_str(&ty_str);
     result.push_str(";");
     Some(result)
@@ -1399,7 +1369,7 @@ fn rewrite_struct_field_type(
     spacing: &str,
     shape: Shape,
 ) -> Option<String> {
-    let ty_shape = try_opt!(shape.offset_left(last_line_width + spacing.len()));
+    let ty_shape = shape.offset_left(last_line_width + spacing.len())?;
     field
         .ty
         .rewrite(context, ty_shape)
@@ -1423,9 +1393,9 @@ pub fn rewrite_struct_field(
     }
 
     let type_annotation_spacing = type_annotation_spacing(context.config);
-    let prefix = try_opt!(rewrite_struct_field_prefix(context, field));
+    let prefix = rewrite_struct_field_prefix(context, field)?;
 
-    let attrs_str = try_opt!(field.attrs.rewrite(context, shape));
+    let attrs_str = field.attrs.rewrite(context, shape)?;
     let attrs_extendable = attrs_str.is_empty()
         || (context.config.attributes_on_same_line_as_field()
             && is_attributes_extendable(&attrs_str));
@@ -1440,14 +1410,14 @@ pub fn rewrite_struct_field(
         ""
     });
     // Try to put everything on a single line.
-    let attr_prefix = try_opt!(combine_strs_with_missing_comments(
+    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 {
@@ -1487,7 +1457,7 @@ pub fn rewrite_struct_field(
             _ => prefix + ty,
         },
         _ => {
-            let ty = try_opt!(rewrite_type_in_next_line());
+            let ty = rewrite_type_in_next_line()?;
             format!(
                 "{}\n{}{}",
                 prefix,
@@ -1530,12 +1500,10 @@ pub fn rewrite_static(
         colon,
     );
     // 2 = " =".len()
-    let ty_str = try_opt!(ty.rewrite(
+    let ty_str = ty.rewrite(
         context,
-        try_opt!(
-            Shape::indented(offset.block_only(), context.config).offset_left(prefix.len() + 2)
-        ),
-    ));
+        Shape::indented(offset.block_only(), context.config).offset_left(prefix.len() + 2)?,
+    )?;
 
     if let Some(expr) = expr_opt {
         let lhs = format!("{}{} =", prefix, ty_str);
@@ -1564,14 +1532,12 @@ pub fn rewrite_associated_type(
 
     let type_bounds_str = if let Some(ty_param_bounds) = ty_param_bounds_opt {
         // 2 = ": ".len()
-        let shape = try_opt!(Shape::indented(indent, context.config).offset_left(prefix.len() + 2));
+        let shape = Shape::indented(indent, context.config).offset_left(prefix.len() + 2)?;
         let bounds: &[_] = ty_param_bounds;
-        let bound_str = try_opt!(
-            bounds
-                .iter()
-                .map(|ty_bound| ty_bound.rewrite(context, shape))
-                .collect::<Option<Vec<_>>>()
-        );
+        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 {
@@ -1582,13 +1548,13 @@ pub fn rewrite_associated_type(
     };
 
     if let Some(ty) = ty_opt {
-        let ty_str = try_opt!(ty.rewrite(
+        let ty_str = ty.rewrite(
             context,
             Shape::legacy(
                 context.budget(indent.block_indent + prefix.len() + 2),
                 indent.block_only(),
             ),
-        ));
+        )?;
         Some(format!("{}{} = {};", prefix, type_bounds_str, ty_str))
     } else {
         Some(format!("{}{};", prefix, type_bounds_str))
@@ -1603,13 +1569,7 @@ pub fn rewrite_associated_impl_type(
     context: &RewriteContext,
     indent: Indent,
 ) -> Option<String> {
-    let result = try_opt!(rewrite_associated_type(
-        ident,
-        ty_opt,
-        ty_param_bounds_opt,
-        context,
-        indent,
-    ));
+    let result = rewrite_associated_type(ident, ty_opt, ty_param_bounds_opt, context, indent)?;
 
     match defaultness {
         ast::Defaultness::Default => Some(format!("default {}", result)),
@@ -1622,7 +1582,7 @@ impl Rewrite for ast::FunctionRetTy {
         match *self {
             ast::FunctionRetTy::Default(_) => Some(String::new()),
             ast::FunctionRetTy::Ty(ref ty) => {
-                let inner_width = try_opt!(shape.width.checked_sub(3));
+                let inner_width = shape.width.checked_sub(3)?;
                 ty.rewrite(context, Shape::legacy(inner_width, shape.indent + 3))
                     .map(|r| format!("-> {}", r))
             }
@@ -1643,10 +1603,8 @@ fn is_empty_infer(context: &RewriteContext, ty: &ast::Ty) -> bool {
 impl Rewrite for ast::Arg {
     fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
         if is_named_arg(self) {
-            let mut result = try_opt!(
-                self.pat
-                    .rewrite(context, Shape::legacy(shape.width, shape.indent))
-            );
+            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_type_annotation() {
@@ -1657,11 +1615,9 @@ impl Rewrite for ast::Arg {
                     result.push_str(" ");
                 }
                 let overhead = last_line_width(&result);
-                let max_width = try_opt!(shape.width.checked_sub(overhead));
-                let ty_str = try_opt!(
-                    self.ty
-                        .rewrite(context, Shape::legacy(max_width, shape.indent))
-                );
+                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);
             }
 
@@ -1682,10 +1638,10 @@ fn rewrite_explicit_self(
             let mut_str = format_mutability(m);
             match lt {
                 Some(ref l) => {
-                    let lifetime_str = try_opt!(l.rewrite(
+                    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)),
@@ -1695,10 +1651,10 @@ fn rewrite_explicit_self(
             assert!(!args.is_empty(), "&[ast::Arg] shouldn't be empty.");
 
             let mutability = explicit_self_mutability(&args[0]);
-            let type_str = try_opt!(ty.rewrite(
+            let type_str = ty.rewrite(
                 context,
                 Shape::legacy(context.config.max_width(), Indent::empty()),
-            ));
+            )?;
 
             Some(format!(
                 "{}self: {}",
@@ -1788,7 +1744,7 @@ fn rewrite_fn_base(
     };
     let fd = fn_sig.decl;
     let g_span = mk_sp(span.lo(), fd.output.span().lo());
-    let generics_str = try_opt!(rewrite_generics(context, fn_sig.generics, shape, g_span));
+    let generics_str = rewrite_generics(context, fn_sig.generics, shape, g_span)?;
     result.push_str(&generics_str);
 
     let snuggle_angle_bracket = generics_str
@@ -1798,16 +1754,14 @@ fn rewrite_fn_base(
 
     // Note that the width and indent don't really matter, we'll re-layout the
     // return type later anyway.
-    let ret_str = try_opt!(
-        fd.output
-            .rewrite(context, Shape::indented(indent, context.config))
-    );
+    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) = try_opt!(compute_budgets_for_args(
+    let (one_line_budget, multi_line_budget, mut arg_indent) = compute_budgets_for_args(
         context,
         &result,
         indent,
@@ -1815,7 +1769,7 @@ fn rewrite_fn_base(
         newline_brace,
         has_body,
         multi_line_ret_str,
-    ));
+    )?;
 
     debug!(
         "rewrite_fn_base: one_line_budget: {}, multi_line_budget: {}, arg_indent: {:?}",
@@ -1869,7 +1823,7 @@ fn rewrite_fn_base(
             .span_after(mk_sp(args_start, span.hi()), "("),
         args_end,
     );
-    let arg_str = try_opt!(rewrite_args(
+    let arg_str = rewrite_args(
         context,
         &fd.inputs,
         fd.get_self().as_ref(),
@@ -1880,7 +1834,7 @@ fn rewrite_fn_base(
         args_span,
         fd.variadic,
         generics_str.contains('\n'),
-    ));
+    )?;
 
     let put_args_in_block = match context.config.fn_args_layout() {
         IndentStyle::Block => arg_str.contains('\n') || arg_str.len() > one_line_budget,
@@ -1968,10 +1922,8 @@ fn rewrite_fn_base(
         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 = try_opt!(
-                fd.output
-                    .rewrite(context, Shape::indented(ret_indent, context.config))
-            );
+            let ret_str = fd.output
+                .rewrite(context, Shape::indented(ret_indent, context.config))?;
             result.push_str(&ret_str);
         } else {
             result.push_str(&ret_str);
@@ -2035,7 +1987,7 @@ fn rewrite_fn_base(
     }
 
     let option = WhereClauseOption::new(!has_body, put_args_in_block && ret_str.is_empty());
-    let where_clause_str = try_opt!(rewrite_where_clause(
+    let where_clause_str = rewrite_where_clause(
         context,
         where_clause,
         context.config.fn_brace_style(),
@@ -2045,7 +1997,7 @@ fn rewrite_fn_base(
         Some(span.hi()),
         pos_before_where,
         option,
-    ));
+    )?;
     // If there are neither where clause nor return type, we may be missing comments between
     // args and `{`.
     if where_clause_str.is_empty() {
@@ -2116,13 +2068,11 @@ fn rewrite_args(
     variadic: bool,
     generics_str_contains_newline: bool,
 ) -> Option<String> {
-    let mut arg_item_strs = try_opt!(
-        args.iter()
-            .map(|arg| {
-                arg.rewrite(context, Shape::legacy(multi_line_budget, arg_indent))
-            })
-            .collect::<Option<Vec<_>>>()
-    );
+    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
@@ -2344,7 +2294,7 @@ fn rewrite_generics(
     shape: Shape,
     span: Span,
 ) -> Option<String> {
-    let g_shape = try_opt!(generics_shape_from_config(context.config, shape, 0));
+    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)
@@ -2452,7 +2402,7 @@ where
         config: context.config,
     };
 
-    let list_str = try_opt!(write_list(&item_vec, &fmt));
+    let list_str = write_list(&item_vec, &fmt)?;
 
     Some(wrap_generics_with_angle_brackets(
         context,
@@ -2494,12 +2444,10 @@ fn rewrite_trait_bounds(
     if bounds.is_empty() {
         return Some(String::new());
     }
-    let bound_str = try_opt!(
-        bounds
-            .iter()
-            .map(|ty_bound| ty_bound.rewrite(context, shape))
-            .collect::<Option<Vec<_>>>()
-    );
+    let bound_str = bounds
+        .iter()
+        .map(|ty_bound| ty_bound.rewrite(context, shape))
+        .collect::<Option<Vec<_>>>()?;
     Some(format!(": {}", join_bounds(context, shape, &bound_str)))
 }
 
@@ -2516,12 +2464,8 @@ fn rewrite_where_clause_rfc_style(
 
     let (span_before, span_after) =
         missing_span_before_after_where(span_end_before_where, where_clause);
-    let (comment_before, comment_after) = try_opt!(rewrite_comments_before_after_where(
-        context,
-        span_before,
-        span_after,
-        shape,
-    ));
+    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()
@@ -2529,9 +2473,9 @@ fn rewrite_where_clause_rfc_style(
         "\n".to_owned() + &block_shape.indent.to_string(context.config)
     };
 
-    let clause_shape = try_opt!(block_shape.block_left(context.config.tab_spaces()));
+    let clause_shape = block_shape.block_left(context.config.tab_spaces())?;
     // 1 = `,`
-    let clause_shape = try_opt!(clause_shape.sub_width(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
@@ -2566,7 +2510,7 @@ fn rewrite_where_clause_rfc_style(
         preserve_newline: true,
         config: context.config,
     };
-    let preds_str = try_opt!(write_list(&items.collect::<Vec<_>>(), &fmt));
+    let preds_str = write_list(&items.collect::<Vec<_>>(), &fmt)?;
 
     let comment_separator = |comment: &str, shape: Shape| if comment.is_empty() {
         String::new()
@@ -2678,7 +2622,7 @@ fn rewrite_where_clause(
         preserve_newline: true,
         config: context.config,
     };
-    let preds_str = try_opt!(write_list(&item_vec, &fmt));
+    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
@@ -2722,12 +2666,12 @@ fn rewrite_comments_before_after_where(
     span_after_where: Span,
     shape: Shape,
 ) -> Option<(String, String)> {
-    let before_comment = try_opt!(rewrite_missing_comment(span_before_where, shape, context));
-    let after_comment = try_opt!(rewrite_missing_comment(
+    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))
 }
 
@@ -2747,12 +2691,12 @@ fn format_generics(
     used_width: usize,
 ) -> Option<String> {
     let shape = Shape::legacy(context.budget(used_width + offset.width()), offset);
-    let mut result = try_opt!(rewrite_generics(context, generics, shape, span));
+    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 option = WhereClauseOption::snuggled(&result);
-        let where_clause_str = try_opt!(rewrite_where_clause(
+        let where_clause_str = rewrite_where_clause(
             context,
             &generics.where_clause,
             brace_style,
@@ -2762,7 +2706,7 @@ fn format_generics(
             Some(span.hi()),
             generics.span.hi(),
             option,
-        ));
+        )?;
         result.push_str(&where_clause_str);
         force_same_line_brace || brace_style == BraceStyle::PreferSameLine
             || (generics.where_clause.predicates.is_empty()
@@ -2795,12 +2739,12 @@ fn format_generics(
 
 impl Rewrite for ast::ForeignItem {
     fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        let attrs_str = try_opt!(self.attrs.rewrite(context, shape));
+        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 = try_opt!(match self.node {
+        let item_str = match self.node {
             ast::ForeignItemKind::Fn(ref fn_decl, ref generics) => {
                 rewrite_fn_base(
                     context,
@@ -2819,7 +2763,7 @@ impl Rewrite for ast::ForeignItem {
                 let mut_str = if is_mutable { "mut " } else { "" };
                 let prefix = format!("{}static {}{}:", vis, mut_str, self.ident);
                 // 1 = ;
-                let shape = try_opt!(shape.sub_width(1));
+                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 {
@@ -2831,7 +2775,7 @@ impl Rewrite for ast::ForeignItem {
                     format!("{}{}{};", prefix, sep, ty_str)
                 })
             }
-        });
+        }?;
 
         let missing_span = if self.attrs.is_empty() {
             mk_sp(self.span.lo(), self.span.lo())
diff --git a/src/lists.rs b/src/lists.rs
index e499377e48a..12fb4032094 100644
--- a/src/lists.rs
+++ b/src/lists.rs
@@ -275,7 +275,7 @@ where
     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 = try_opt!(item.item.as_ref());
+        let inner_item = item.item.as_ref()?;
         let first = i == 0;
         let last = iter.peek().is_none();
         let mut separate = !last || trailing_separator;
@@ -336,12 +336,8 @@ where
             // Block style in non-vertical mode.
             let block_mode = tactic != DefinitiveListTactic::Vertical;
             // Width restriction is only relevant in vertical mode.
-            let comment = try_opt!(rewrite_comment(
-                comment,
-                block_mode,
-                formatting.shape,
-                formatting.config,
-            ));
+            let comment =
+                rewrite_comment(comment, block_mode, formatting.shape, formatting.config)?;
             result.push_str(&comment);
 
             if tactic == DefinitiveListTactic::Vertical {
@@ -377,12 +373,12 @@ where
         // Post-comments
         if tactic != DefinitiveListTactic::Vertical && item.post_comment.is_some() {
             let comment = item.post_comment.as_ref().unwrap();
-            let formatted_comment = try_opt!(rewrite_comment(
+            let formatted_comment = rewrite_comment(
                 comment,
                 true,
                 Shape::legacy(formatting.shape.width, Indent::empty()),
                 formatting.config,
-            ));
+            )?;
 
             result.push(' ');
             result.push_str(&formatted_comment);
@@ -423,7 +419,7 @@ where
                 rewrite_comment(comment, block_style, comment_shape, formatting.config)
             };
 
-            let mut formatted_comment = try_opt!(rewrite_post_comment(&mut item_max_width));
+            let mut formatted_comment = rewrite_post_comment(&mut item_max_width)?;
 
             if !formatted_comment.starts_with('\n') {
                 let mut comment_alignment =
@@ -432,7 +428,7 @@ where
                     + comment_alignment + 1 > formatting.config.max_width()
                 {
                     item_max_width = None;
-                    formatted_comment = try_opt!(rewrite_post_comment(&mut item_max_width));
+                    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) {
@@ -742,9 +738,10 @@ pub fn struct_lit_shape(
     suffix_width: usize,
 ) -> Option<(Option<Shape>, Shape)> {
     let v_shape = match context.config.struct_lit_style() {
-        IndentStyle::Visual => try_opt!(
-            try_opt!(shape.visual_indent(0).shrink_left(prefix_width)).sub_width(suffix_width)
-        ),
+        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 {
diff --git a/src/macros.rs b/src/macros.rs
index 4eaf97dd254..470f1e84fd8 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -216,7 +216,7 @@ pub fn rewrite_macro(
             })
         }
         MacroStyle::Brackets => {
-            let mac_shape = try_opt!(shape.offset_left(macro_name.len()));
+            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_square_brackets() {
@@ -227,8 +227,8 @@ pub fn rewrite_macro(
                 // 6 = `vec!` + `; `
                 let total_overhead = lbr.len() + rbr.len() + 6;
                 let nested_shape = mac_shape.block_indent(context.config.tab_spaces());
-                let lhs = try_opt!(arg_vec[0].rewrite(context, nested_shape));
-                let rhs = try_opt!(arg_vec[1].rewrite(context, nested_shape));
+                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
                 {
@@ -271,13 +271,8 @@ pub fn rewrite_macro(
                         .span_after(mac.span, original_style.opener()),
                     mac.span.hi() - BytePos(1),
                 );
-                let rewrite = try_opt!(rewrite_array(
-                    expr_vec.iter(),
-                    sp,
-                    context,
-                    mac_shape,
-                    trailing_comma,
-                ));
+                let rewrite =
+                    rewrite_array(expr_vec.iter(), sp, context, mac_shape, trailing_comma)?;
 
                 Some(format!("{}{}", macro_name, rewrite))
             }
@@ -299,7 +294,7 @@ pub fn convert_try_mac(mac: &ast::Mac, context: &RewriteContext) -> Option<ast::
 
         Some(ast::Expr {
             id: ast::NodeId::new(0), // dummy value
-            node: ast::ExprKind::Try(try_opt!(parser.parse_expr().ok())),
+            node: ast::ExprKind::Try(parser.parse_expr().ok()?),
             span: mac.span, // incorrect span, but shouldn't matter too much
             attrs: ThinVec::new(),
         })
@@ -354,22 +349,20 @@ fn indent_macro_snippet(
     indent: Indent,
 ) -> Option<String> {
     let mut lines = macro_str.lines();
-    let first_line = try_opt!(lines.next().map(|s| s.trim_right()));
+    let first_line = lines.next().map(|s| s.trim_right())?;
     let mut trimmed_lines = Vec::with_capacity(16);
 
-    let min_prefix_space_width = try_opt!(
-        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()
-    );
+    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"
diff --git a/src/patterns.rs b/src/patterns.rs
index 6d289736c51..4df36b87e4d 100644
--- a/src/patterns.rs
+++ b/src/patterns.rs
@@ -38,14 +38,12 @@ impl Rewrite for Pat {
                 let sub_pat = match *sub_pat {
                     Some(ref p) => {
                         // 3 - ` @ `.
-                        let width = try_opt!(
-                            shape
-                                .width
-                                .checked_sub(prefix.len() + mut_infix.len() + id_str.len() + 3)
-                        );
+                        let width = shape
+                            .width
+                            .checked_sub(prefix.len() + mut_infix.len() + id_str.len() + 3)?;
                         format!(
                             " @ {}",
-                            try_opt!(p.rewrite(context, Shape::legacy(width, shape.indent)))
+                            p.rewrite(context, Shape::legacy(width, shape.indent))?
                         )
                     }
                     None => "".to_owned(),
@@ -86,8 +84,7 @@ impl Rewrite for Pat {
                 rewrite_path(context, PathContext::Expr, q_self.as_ref(), path, shape)
             }
             PatKind::TupleStruct(ref path, ref pat_vec, dotdot_pos) => {
-                let path_str =
-                    try_opt!(rewrite_path(context, PathContext::Expr, None, path, shape));
+                let path_str = rewrite_path(context, PathContext::Expr, None, path, shape)?;
                 rewrite_tuple_pat(
                     pat_vec,
                     dotdot_pos,
@@ -101,9 +98,9 @@ impl Rewrite for Pat {
             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!("{}..", try_opt!(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.
@@ -111,7 +108,7 @@ impl Rewrite for Pat {
                     prefix.chain(slice_pat.into_iter()).chain(suffix).collect();
 
                 // Check that all the rewrites succeeded, and if not return None.
-                let pats = try_opt!(pats);
+                let pats = pats?;
 
                 // Unwrap all the sub-strings and join them with commas.
                 let result = if context.config.spaces_within_square_brackets() {
@@ -139,14 +136,8 @@ fn rewrite_struct_pat(
     shape: Shape,
 ) -> Option<String> {
     // 2 =  ` {`
-    let path_shape = try_opt!(shape.sub_width(2));
-    let path_str = try_opt!(rewrite_path(
-        context,
-        PathContext::Expr,
-        None,
-        path,
-        path_shape,
-    ));
+    let path_shape = shape.sub_width(2)?;
+    let path_str = rewrite_path(context, PathContext::Expr, None, path, path_shape)?;
 
     if fields.is_empty() && !elipses {
         return Some(format!("{} {{}}", path_str));
@@ -155,12 +146,8 @@ fn rewrite_struct_pat(
     let (elipses_str, terminator) = if elipses { (", ..", "..") } else { ("", "}") };
 
     // 3 = ` { `, 2 = ` }`.
-    let (h_shape, v_shape) = try_opt!(struct_lit_shape(
-        shape,
-        context,
-        path_str.len() + 3,
-        elipses_str.len() + 2,
-    ));
+    let (h_shape, v_shape) =
+        struct_lit_shape(shape, context, path_str.len() + 3, elipses_str.len() + 2)?;
 
     let items = itemize_list(
         context.codemap,
@@ -179,7 +166,7 @@ fn rewrite_struct_pat(
     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 = try_opt!(write_list(&item_vec, &fmt));
+    let mut fields_str = write_list(&item_vec, &fmt)?;
     let one_line_width = h_shape.map_or(0, |shape| shape.width);
 
     if elipses {
@@ -215,14 +202,14 @@ impl Rewrite for FieldPat {
         if self.is_shorthand {
             pat
         } else {
-            let pat_str = try_opt!(pat);
+            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 = try_opt!(self.pat.rewrite(context, nested_shape));
+                let pat_str = self.pat.rewrite(context, nested_shape)?;
                 Some(format!(
                     "{}:\n{}{}",
                     id_str,
diff --git a/src/shape.rs b/src/shape.rs
index 63910c29707..b5d57997e87 100644
--- a/src/shape.rs
+++ b/src/shape.rs
@@ -229,14 +229,14 @@ impl Shape {
 
     pub fn sub_width(&self, width: usize) -> Option<Shape> {
         Some(Shape {
-            width: try_opt!(self.width.checked_sub(width)),
+            width: self.width.checked_sub(width)?,
             ..*self
         })
     }
 
     pub fn shrink_left(&self, width: usize) -> Option<Shape> {
         Some(Shape {
-            width: try_opt!(self.width.checked_sub(width)),
+            width: self.width.checked_sub(width)?,
             indent: self.indent + width,
             offset: self.offset + width,
         })
diff --git a/src/string.rs b/src/string.rs
index efec7ff2377..c072d3186a2 100644
--- a/src/string.rs
+++ b/src/string.rs
@@ -67,7 +67,7 @@ pub fn rewrite_string<'a>(orig: &str, fmt: &StringFormat<'a>) -> Option<String>
     let ender_length = fmt.line_end.len();
     // If we cannot put at least a single character per line, the rewrite won't
     // succeed.
-    let max_chars = try_opt!(shape.width.checked_sub(fmt.opener.len() + ender_length + 1)) + 1;
+    let 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.
diff --git a/src/types.rs b/src/types.rs
index 060871df161..c17112c9404 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -58,7 +58,7 @@ pub fn rewrite_path(
             result.push_str(" ")
         }
 
-        let fmt_ty = try_opt!(qself.ty.rewrite(context, shape));
+        let fmt_ty = qself.ty.rewrite(context, shape)?;
         result.push_str(&fmt_ty);
 
         if skip_count > 0 {
@@ -69,9 +69,9 @@ pub fn rewrite_path(
 
             let extra_offset = extra_offset(&result, shape);
             // 3 = ">::".len()
-            let shape = try_opt!(try_opt!(shape.shrink_left(extra_offset)).sub_width(3));
+            let shape = shape.shrink_left(extra_offset)?.sub_width(3)?;
 
-            result = try_opt!(rewrite_path_segments(
+            result = rewrite_path_segments(
                 PathContext::Type,
                 result,
                 path.segments.iter().take(skip_count),
@@ -79,7 +79,7 @@ pub fn rewrite_path(
                 path.span.hi(),
                 context,
                 shape,
-            ));
+            )?;
         }
 
         if context.config.spaces_within_angle_brackets() {
@@ -128,15 +128,15 @@ where
         }
 
         let extra_offset = extra_offset(&buffer, shape);
-        let new_shape = try_opt!(shape.shrink_left(extra_offset));
-        let segment_string = try_opt!(rewrite_segment(
+        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);
     }
@@ -171,12 +171,10 @@ impl<'a> Rewrite for SegmentParam<'a> {
                     TypeDensity::Wide => format!("{} = ", binding.ident),
                     TypeDensity::Compressed => format!("{}=", binding.ident),
                 };
-                let budget = try_opt!(shape.width.checked_sub(result.len()));
-                let rewrite = try_opt!(
-                    binding
-                        .ty
-                        .rewrite(context, Shape::legacy(budget, shape.indent + result.len()))
-                );
+                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)
             }
@@ -203,7 +201,7 @@ fn rewrite_segment(
     shape: Shape,
 ) -> Option<String> {
     let ident_len = segment.identifier.to_string().len();
-    let shape = try_opt!(shape.shrink_left(ident_len));
+    let shape = shape.shrink_left(ident_len)?;
 
     let params = if let Some(ref params) = segment.parameters {
         match **params {
@@ -226,12 +224,9 @@ fn rewrite_segment(
                     ""
                 };
 
-                let generics_shape = try_opt!(generics_shape_from_config(
-                    context.config,
-                    shape,
-                    separator.len(),
-                ));
-                let one_line_width = try_opt!(shape.width.checked_sub(separator.len() + 2));
+                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(),
@@ -243,12 +238,8 @@ fn rewrite_segment(
                     span_hi,
                     false,
                 );
-                let generics_str = try_opt!(format_generics_item_list(
-                    context,
-                    items,
-                    generics_shape,
-                    one_line_width,
-                ));
+                let generics_str =
+                    format_generics_item_list(context, items, generics_shape, one_line_width)?;
 
                 // Update position of last bracket.
                 *span_lo = next_span_lo;
@@ -260,14 +251,14 @@ fn rewrite_segment(
                     Some(ref ty) => FunctionRetTy::Ty(ty.clone()),
                     None => FunctionRetTy::Default(codemap::DUMMY_SP),
                 };
-                try_opt!(format_function_type(
+                format_function_type(
                     data.inputs.iter().map(|x| &**x),
                     &output,
                     false,
                     data.span,
                     context,
                     shape,
-                ))
+                )?
             }
             _ => String::new(),
         }
@@ -310,7 +301,7 @@ where
     };
 
     // 2 for ()
-    let budget = try_opt!(shape.width.checked_sub(2));
+    let budget = shape.width.checked_sub(2)?;
     // 1 for (
     let offset = match context.config.fn_args_layout() {
         IndentStyle::Block => {
@@ -372,21 +363,21 @@ where
         config: context.config,
     };
 
-    let list_str = try_opt!(write_list(&item_vec, &fmt));
+    let list_str = write_list(&item_vec, &fmt)?;
 
     let ty_shape = match context.config.fn_args_layout() {
         IndentStyle::Block => shape.block().block_indent(context.config.tab_spaces()),
-        IndentStyle::Visual => try_opt!(shape.block_left(4)),
+        IndentStyle::Visual => shape.block_left(4)?,
     };
     let output = match *output {
         FunctionRetTy::Ty(ref ty) => {
-            let type_str = try_opt!(ty.rewrite(context, ty_shape));
+            let type_str = ty.rewrite(context, ty_shape)?;
             format!(" -> {}", type_str)
         }
         FunctionRetTy::Default(..) => String::new(),
     };
 
-    let shape = try_opt!(shape.sub_width(output.len()));
+    let shape = shape.sub_width(output.len())?;
     let extendable = !list_str.contains('\n') || list_str.is_empty();
     let args = wrap_args_with_parens(
         context,
@@ -424,27 +415,24 @@ impl Rewrite for ast::WherePredicate {
                 ref bounds,
                 ..
             }) => {
-                let type_str = try_opt!(bounded_ty.rewrite(context, shape));
+                let type_str = bounded_ty.rewrite(context, shape)?;
 
                 let colon = type_bound_colon(context);
 
                 if !bound_lifetimes.is_empty() {
-                    let lifetime_str: String = try_opt!(
-                        bound_lifetimes
-                            .iter()
-                            .map(|lt| lt.rewrite(context, shape))
-                            .collect::<Option<Vec<_>>>()
-                    ).join(", ");
+                    let lifetime_str: String = bound_lifetimes
+                        .iter()
+                        .map(|lt| lt.rewrite(context, shape))
+                        .collect::<Option<Vec<_>>>()?
+                        .join(", ");
 
                     // 6 = "for<> ".len()
                     let used_width = lifetime_str.len() + type_str.len() + colon.len() + 6;
-                    let ty_shape = try_opt!(shape.offset_left(used_width));
-                    let bounds: Vec<_> = try_opt!(
-                        bounds
-                            .iter()
-                            .map(|ty_bound| ty_bound.rewrite(context, ty_shape))
-                            .collect()
-                    );
+                    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_angle_brackets() && !lifetime_str.is_empty() {
@@ -461,18 +449,15 @@ impl Rewrite for ast::WherePredicate {
                 } else {
                     let used_width = type_str.len() + colon.len();
                     let ty_shape = match context.config.where_style() {
-                        Style::Legacy => try_opt!(shape.block_left(used_width)),
+                        Style::Legacy => shape.block_left(used_width)?,
                         Style::Rfc => shape,
                     };
-                    let bounds: Vec<_> = try_opt!(
-                        bounds
-                            .iter()
-                            .map(|ty_bound| ty_bound.rewrite(context, ty_shape))
-                            .collect()
-                    );
+                    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, try_opt!(ty_shape.sub_width(overhead)), &bounds);
+                    let bounds_str = join_bounds(context, ty_shape.sub_width(overhead)?, &bounds);
 
                     format!("{}{}{}", type_str, colon, bounds_str)
                 }
@@ -481,24 +466,18 @@ impl Rewrite for ast::WherePredicate {
                 ref lifetime,
                 ref bounds,
                 ..
-            }) => try_opt!(rewrite_bounded_lifetime(
-                lifetime,
-                bounds.iter(),
-                context,
-                shape,
-            )),
+            }) => rewrite_bounded_lifetime(lifetime, bounds.iter(), context, shape)?,
             ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
                 ref lhs_ty,
                 ref rhs_ty,
                 ..
             }) => {
-                let lhs_ty_str = try_opt!(lhs_ty.rewrite(context, shape));
+                let lhs_ty_str = lhs_ty.rewrite(context, shape)?;
                 // 3 = " = ".len()
                 let used_width = 3 + lhs_ty_str.len();
-                let budget = try_opt!(shape.width.checked_sub(used_width));
-                let rhs_ty_str = try_opt!(
-                    rhs_ty.rewrite(context, Shape::legacy(budget, shape.indent + used_width))
-                );
+                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)
             }
         };
@@ -522,24 +501,22 @@ fn rewrite_bounded_lifetime<'b, I>(
 where
     I: ExactSizeIterator<Item = &'b ast::Lifetime>,
 {
-    let result = try_opt!(lt.rewrite(context, shape));
+    let result = lt.rewrite(context, shape)?;
 
     if bounds.len() == 0 {
         Some(result)
     } else {
-        let appendix: Vec<_> = try_opt!(
-            bounds
-                .into_iter()
-                .map(|b| b.rewrite(context, shape))
-                .collect()
-        );
+        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, try_opt!(shape.sub_width(overhead)), &appendix)
+            join_bounds(context, shape.sub_width(overhead)?, &appendix)
         );
         Some(result)
     }
@@ -554,7 +531,7 @@ impl Rewrite for ast::TyParamBound {
             ast::TyParamBound::TraitTyParamBound(ref tref, ast::TraitBoundModifier::Maybe) => {
                 Some(format!(
                     "?{}",
-                    try_opt!(tref.rewrite(context, try_opt!(shape.offset_left(1))))
+                    tref.rewrite(context, shape.offset_left(1)?)?
                 ))
             }
             ast::TyParamBound::RegionTyParamBound(ref l) => l.rewrite(context, shape),
@@ -570,7 +547,9 @@ impl Rewrite for ast::Lifetime {
 
 impl Rewrite for ast::TyParamBounds {
     fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        let strs: Vec<_> = try_opt!(self.iter().map(|b| b.rewrite(context, shape)).collect());
+        let strs = self.iter()
+            .map(|b| b.rewrite(context, shape))
+            .collect::<Option<Vec<_>>>()?;
         join_bounds(context, shape, &strs).rewrite(context, shape)
     }
 }
@@ -586,12 +565,10 @@ impl Rewrite for ast::TyParam {
         result.push_str(&self.ident.to_string());
         if !self.bounds.is_empty() {
             result.push_str(type_bound_colon(context));
-            let strs: Vec<_> = try_opt!(
-                self.bounds
-                    .iter()
-                    .map(|ty_bound| ty_bound.rewrite(context, shape))
-                    .collect()
-            );
+            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 {
@@ -600,9 +577,8 @@ impl Rewrite for ast::TyParam {
                 TypeDensity::Wide => " = ",
             };
             result.push_str(eq_str);
-            let budget = try_opt!(shape.width.checked_sub(result.len()));
-            let rewrite =
-                try_opt!(def.rewrite(context, Shape::legacy(budget, shape.indent + result.len())));
+            let budget = shape.width.checked_sub(result.len())?;
+            let rewrite = def.rewrite(context, Shape::legacy(budget, shape.indent + result.len()))?;
             result.push_str(&rewrite);
         }
 
@@ -613,19 +589,16 @@ impl Rewrite for ast::TyParam {
 impl Rewrite for ast::PolyTraitRef {
     fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
         if !self.bound_lifetimes.is_empty() {
-            let lifetime_str: String = try_opt!(
-                self.bound_lifetimes
-                    .iter()
-                    .map(|lt| lt.rewrite(context, shape))
-                    .collect::<Option<Vec<_>>>()
-            ).join(", ");
+            let lifetime_str: String = self.bound_lifetimes
+                .iter()
+                .map(|lt| lt.rewrite(context, shape))
+                .collect::<Option<Vec<_>>>()?
+                .join(", ");
 
             // 6 is "for<> ".len()
             let extra_offset = lifetime_str.len() + 6;
-            let path_str = try_opt!(
-                self.trait_ref
-                    .rewrite(context, try_opt!(shape.offset_left(extra_offset)))
-            );
+            let path_str = self.trait_ref
+                .rewrite(context, shape.offset_left(extra_offset)?)?;
 
             Some(
                 if context.config.spaces_within_angle_brackets() && !lifetime_str.is_empty() {
@@ -663,34 +636,32 @@ impl Rewrite for ast::Ty {
                 let mut_len = mut_str.len();
                 Some(match *lifetime {
                     Some(ref lifetime) => {
-                        let lt_budget = try_opt!(shape.width.checked_sub(2 + mut_len));
-                        let lt_str = try_opt!(lifetime.rewrite(
+                        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 = try_opt!(shape.width.checked_sub(2 + mut_len + lt_len));
+                        let budget = shape.width.checked_sub(2 + mut_len + lt_len)?;
                         format!(
                             "&{} {}{}",
                             lt_str,
                             mut_str,
-                            try_opt!(mt.ty.rewrite(
+                            mt.ty.rewrite(
                                 context,
-                                Shape::legacy(budget, shape.indent + 2 + mut_len + lt_len),
-                            ))
+                                Shape::legacy(budget, shape.indent + 2 + mut_len + lt_len)
+                            )?
                         )
                     }
                     None => {
-                        let budget = try_opt!(shape.width.checked_sub(1 + mut_len));
+                        let budget = shape.width.checked_sub(1 + mut_len)?;
                         format!(
                             "&{}{}",
                             mut_str,
-                            try_opt!(
-                                mt.ty.rewrite(
-                                    context,
-                                    Shape::legacy(budget, shape.indent + 1 + mut_len),
-                                )
-                            )
+                            mt.ty.rewrite(
+                                context,
+                                Shape::legacy(budget, shape.indent + 1 + mut_len),
+                            )?
                         )
                     }
                 })
@@ -698,7 +669,7 @@ impl Rewrite for ast::Ty {
             // FIXME: we drop any comments here, even though it's a silly place to put
             // comments.
             ast::TyKind::Paren(ref ty) => {
-                let budget = try_opt!(shape.width.checked_sub(2));
+                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() {
                         format!("( {} )", ty_str)
@@ -708,9 +679,9 @@ impl Rewrite for ast::Ty {
             }
             ast::TyKind::Slice(ref ty) => {
                 let budget = if context.config.spaces_within_square_brackets() {
-                    try_opt!(shape.width.checked_sub(4))
+                    shape.width.checked_sub(4)?
                 } else {
-                    try_opt!(shape.width.checked_sub(2))
+                    shape.width.checked_sub(2)?
                 };
                 ty.rewrite(context, Shape::legacy(budget, shape.indent + 1))
                     .map(|ty_str| if context.config.spaces_within_square_brackets() {
@@ -772,18 +743,17 @@ fn rewrite_bare_fn(
         // 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(&try_opt!(
-            bare_fn
-                .lifetimes
-                .iter()
-                .map(|l| {
-                    l.rewrite(
-                        context,
-                        Shape::legacy(try_opt!(shape.width.checked_sub(6)), shape.indent + 4),
-                    )
-                })
-                .collect::<Option<Vec<_>>>()
-        ).join(", "));
+        result.push_str(&bare_fn
+            .lifetimes
+            .iter()
+            .map(|l| {
+                l.rewrite(
+                    context,
+                    Shape::legacy(shape.width.checked_sub(6)?, shape.indent + 4),
+                )
+            })
+            .collect::<Option<Vec<_>>>()?
+            .join(", "));
         result.push_str("> ");
     }
 
@@ -797,16 +767,16 @@ fn rewrite_bare_fn(
 
     result.push_str("fn");
 
-    let func_ty_shape = try_opt!(shape.offset_left(result.len()));
+    let func_ty_shape = shape.offset_left(result.len())?;
 
-    let rewrite = try_opt!(format_function_type(
+    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);
 
diff --git a/src/utils.rs b/src/utils.rs
index a01e22aae29..d1324f1dafa 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -343,15 +343,6 @@ macro_rules! impl_enum_serialize_and_deserialize {
     };
 }
 
-// Same as try!, but for Option
-#[macro_export]
-macro_rules! try_opt {
-    ($expr:expr) => (match $expr {
-        Some(val) => val,
-        None => { return None; }
-    })
-}
-
 macro_rules! msg {
     ($($arg:tt)*) => (
         match writeln!(&mut ::std::io::stderr(), $($arg)* ) {
diff --git a/src/vertical.rs b/src/vertical.rs
index 4f19cd17921..f5636672422 100644
--- a/src/vertical.rs
+++ b/src/vertical.rs
@@ -48,7 +48,7 @@ impl AlignedItem for ast::StructField {
     }
 
     fn rewrite_prefix(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        let attrs_str = try_opt!(self.attrs.rewrite(context, shape));
+        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 {
@@ -88,7 +88,7 @@ impl AlignedItem for ast::Field {
     }
 
     fn rewrite_prefix(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
-        let attrs_str = try_opt!(self.attrs.rewrite(context, shape));
+        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())
@@ -166,24 +166,13 @@ pub fn rewrite_with_alignment<T: AlignedItem>(
     };
     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 = try_opt!(rewrite_aligned_items_inner(
-        context,
-        init,
-        init_span,
-        shape.indent,
-        one_line_width,
-    ));
+    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 = try_opt!(rewrite_with_alignment(
-            rest,
-            context,
-            shape,
-            rest_span,
-            one_line_width,
-        ));
+        let rest_str = rewrite_with_alignment(rest, context, shape, rest_span, one_line_width)?;
         Some(
             result + spaces + "\n"
                 + &shape
@@ -228,7 +217,7 @@ fn rewrite_aligned_items_inner<T: AlignedItem>(
 ) -> Option<String> {
     let item_indent = offset.block_indent(context.config);
     // 1 = ","
-    let item_shape = try_opt!(Shape::indented(item_indent, context.config).sub_width(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_preix_max_min_width(context, fields, item_shape);
     let max_diff = field_prefix_max_width
diff --git a/src/visitor.rs b/src/visitor.rs
index ddbbbd49eaa..80faa78a6fa 100644
--- a/src/visitor.rs
+++ b/src/visitor.rs
@@ -811,12 +811,10 @@ impl Rewrite for ast::MetaItem {
             ast::MetaItemKind::List(ref list) => {
                 let name = self.name.as_str();
                 // 1 = `(`, 2 = `]` and `)`
-                let item_shape = try_opt!(
-                    shape
-                        .visual_indent(0)
-                        .shrink_left(name.len() + 1)
-                        .and_then(|s| s.sub_width(2))
-                );
+                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(),
@@ -839,13 +837,13 @@ impl Rewrite for ast::MetaItem {
                     preserve_newline: false,
                     config: context.config,
                 };
-                format!("{}({})", name, try_opt!(write_list(&item_vec, &fmt)))
+                format!("{}({})", name, write_list(&item_vec, &fmt)?)
             }
             ast::MetaItemKind::NameValue(ref literal) => {
                 let name = self.name.as_str();
                 // 3 = ` = `
-                let lit_shape = try_opt!(shape.shrink_left(name.len() + 3));
-                let value = try_opt!(rewrite_literal(context, literal, lit_shape));
+                let lit_shape = shape.shrink_left(name.len() + 3)?;
+                let value = rewrite_literal(context, literal, lit_shape)?;
                 format!("{} = {}", name, value)
             }
         })
@@ -872,8 +870,8 @@ impl Rewrite for ast::Attribute {
                 return Some(snippet);
             }
             // 1 = `[`
-            let shape = try_opt!(shape.offset_left(prefix.len() + 1));
-            try_opt!(self.meta())
+            let shape = shape.offset_left(prefix.len() + 1)?;
+            self.meta()?
                 .rewrite(context, shape)
                 .map(|rw| format!("{}[{}]", prefix, rw))
         }
@@ -894,7 +892,7 @@ impl<'a> Rewrite for [ast::Attribute] {
         let mut insert_new_line = true;
         let mut is_prev_sugared_doc = false;
         while let Some((i, a)) = iter.next() {
-            let a_str = try_opt!(a.rewrite(context, shape));
+            let a_str = a.rewrite(context, shape)?;
 
             // Write comments and blank lines between attributes.
             if i > 0 {
@@ -926,12 +924,12 @@ impl<'a> Rewrite for [ast::Attribute] {
                     (false, false)
                 };
 
-                let comment = try_opt!(recover_missing_comment_in_span(
+                let comment = recover_missing_comment_in_span(
                     mk_sp(self[i - 1].span.hi(), a.span.lo()),
                     shape.with_max_width(context.config),
                     context,
                     0,
-                ));
+                )?;
 
                 if !comment.is_empty() {
                     if multi_line_before {
@@ -966,7 +964,7 @@ impl<'a> Rewrite for [ast::Attribute] {
                         Some(&(_, next_attr)) if is_derive(next_attr) => insert_new_line = false,
                         // If not, rewrite the merged derives.
                         _ => {
-                            result.push_str(&try_opt!(format_derive(context, &derive_args, shape)));
+                            result.push_str(&format_derive(context, &derive_args, shape)?);
                             derive_args.clear();
                         }
                     }
@@ -988,7 +986,7 @@ fn format_derive(context: &RewriteContext, derive_args: &[String], shape: Shape)
     let mut result = String::with_capacity(128);
     result.push_str("#[derive(");
     // 11 = `#[derive()]`
-    let initial_budget = try_opt!(shape.width.checked_sub(11));
+    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() {