about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2016-05-28 21:50:25 +0100
committerNick Cameron <ncameron@mozilla.com>2016-05-29 09:32:48 +0100
commitbbb6038b92aa1ce17eebad96a904543e867f18b2 (patch)
tree2ed3eaa253cdc221a00fd030126489f4f6421d8e
parent6e01fac285169c24db8e8c64d3bea0d368197650 (diff)
Treat chains with just expr? specially.
Fixes #1004
-rw-r--r--src/chains.rs28
-rw-r--r--tests/source/chains.rs15
-rw-r--r--tests/target/chains.rs13
3 files changed, 56 insertions, 0 deletions
diff --git a/src/chains.rs b/src/chains.rs
index faf368d41c1..00895561ded 100644
--- a/src/chains.rs
+++ b/src/chains.rs
@@ -88,6 +88,7 @@ use expr::rewrite_call;
 use config::BlockIndentStyle;
 use macros::convert_try_mac;
 
+use std::iter;
 use syntax::{ast, ptr};
 use syntax::codemap::{mk_sp, Span};
 
@@ -99,6 +100,12 @@ pub fn rewrite_chain(expr: &ast::Expr,
     let total_span = expr.span;
     let (parent, subexpr_list) = make_subexpr_list(expr, context);
 
+    // Bail out if the chain is just try sugar, i.e., an expression followed by
+    // any number of `?`s.
+    if chain_only_try(&subexpr_list) {
+        return rewrite_try(&parent, subexpr_list.len(), context, width, offset);
+    }
+
     // Parent is the first item in the chain, e.g., `foo` in `foo.bar.baz()`.
     let parent_block_indent = chain_base_indent(context, offset);
     let parent_context = &RewriteContext { block_indent: parent_block_indent, ..*context };
@@ -196,6 +203,27 @@ pub fn rewrite_chain(expr: &ast::Expr,
              offset)
 }
 
+// True if the chain is only `?`s.
+fn chain_only_try(exprs: &[ast::Expr]) -> bool {
+    exprs.iter().all(|e| if let ast::ExprKind::Try(_) = e.node {
+        true
+    } else {
+        false
+    })
+}
+
+pub fn rewrite_try(expr: &ast::Expr,
+                   try_count: usize,
+                   context: &RewriteContext,
+                   width: usize,
+                   offset: Indent)
+                   -> Option<String> {
+    let sub_expr = try_opt!(expr.rewrite(context, width - try_count, offset));
+    Some(format!("{}{}",
+                 sub_expr,
+                 iter::repeat("?").take(try_count).collect::<String>()))
+}
+
 fn join_rewrites(rewrites: &[String], subexps: &[ast::Expr], connector: &str) -> String {
     let mut rewrite_iter = rewrites.iter();
     let mut result = rewrite_iter.next().unwrap().clone();
diff --git a/tests/source/chains.rs b/tests/source/chains.rs
index 66c982082e7..deed8f6d8d8 100644
--- a/tests/source/chains.rs
+++ b/tests/source/chains.rs
@@ -133,3 +133,18 @@ fn try_shorthand() {
                               |tcx| tcx.lookup_item_type(def_id).generics)?;
     fooooooooooooooooooooooooooo()?.bar()?.baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz()?;
 }
+
+fn issue_1004() {
+         match *self {
+                ty::ImplOrTraitItem::MethodTraitItem(ref i) => write!(f, "{:?}", i),
+                ty::ImplOrTraitItem::ConstTraitItem(ref i) => write!(f, "{:?}", i),
+                ty::ImplOrTraitItem::TypeTraitItem(ref i) => write!(f, "{:?}", i),
+            }
+            ?;
+
+            ty::tls::with(|tcx| {
+                let tap = ty::Binder(TraitAndProjections(principal, projections));
+                in_binder(f, tcx, &ty::Binder(""), Some(tap))
+            })
+            ?;
+}
diff --git a/tests/target/chains.rs b/tests/target/chains.rs
index 3004946fb56..bdcb9fbd60e 100644
--- a/tests/target/chains.rs
+++ b/tests/target/chains.rs
@@ -162,3 +162,16 @@ fn try_shorthand() {
         .bar()?
         .baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz()?;
 }
+
+fn issue_1004() {
+    match *self {
+        ty::ImplOrTraitItem::MethodTraitItem(ref i) => write!(f, "{:?}", i),
+        ty::ImplOrTraitItem::ConstTraitItem(ref i) => write!(f, "{:?}", i),
+        ty::ImplOrTraitItem::TypeTraitItem(ref i) => write!(f, "{:?}", i),
+    }?;
+
+    ty::tls::with(|tcx| {
+        let tap = ty::Binder(TraitAndProjections(principal, projections));
+        in_binder(f, tcx, &ty::Binder(""), Some(tap))
+    })?;
+}