From bbb6038b92aa1ce17eebad96a904543e867f18b2 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Sat, 28 May 2016 21:50:25 +0100 Subject: [PATCH] Treat chains with just expr? specially. Fixes #1004 --- src/chains.rs | 28 ++++++++++++++++++++++++++++ tests/source/chains.rs | 15 +++++++++++++++ tests/target/chains.rs | 13 +++++++++++++ 3 files changed, 56 insertions(+) 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 { + let sub_expr = try_opt!(expr.rewrite(context, width - try_count, offset)); + Some(format!("{}{}", + sub_expr, + iter::repeat("?").take(try_count).collect::())) +} + 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)) + })?; +}