Fix handling of match arm's rewrite (#3775)

This commit is contained in:
Seiichi Uchida 2019-09-05 11:15:46 +09:00 committed by GitHub
parent e81ec20af0
commit 783948fcbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 95 additions and 31 deletions

View File

@ -190,24 +190,6 @@ fn return_macro_parse_failure_fallback(
Some(context.snippet(span).to_owned())
}
struct InsideMacroGuard<'a> {
context: &'a RewriteContext<'a>,
is_nested: bool,
}
impl<'a> InsideMacroGuard<'a> {
fn inside_macro_context(context: &'a RewriteContext<'_>) -> InsideMacroGuard<'a> {
let is_nested = context.inside_macro.replace(true);
InsideMacroGuard { context, is_nested }
}
}
impl<'a> Drop for InsideMacroGuard<'a> {
fn drop(&mut self) {
self.context.inside_macro.replace(self.is_nested);
}
}
pub(crate) fn rewrite_macro(
mac: &ast::Mac,
extra_ident: Option<ast::Ident>,
@ -221,9 +203,16 @@ pub(crate) fn rewrite_macro(
if should_skip {
None
} else {
let guard = InsideMacroGuard::inside_macro_context(context);
let guard = context.enter_macro();
let result = catch_unwind(AssertUnwindSafe(|| {
rewrite_macro_inner(mac, extra_ident, context, shape, position, guard.is_nested)
rewrite_macro_inner(
mac,
extra_ident,
context,
shape,
position,
guard.is_nested(),
)
}));
match result {
Err(..) | Ok(None) => {
@ -263,7 +252,7 @@ fn rewrite_macro_inner(
) -> Option<String> {
if context.config.use_try_shorthand() {
if let Some(expr) = convert_try_mac(mac, context) {
context.inside_macro.replace(false);
context.leave_macro();
return expr.rewrite(context, shape);
}
}
@ -412,7 +401,7 @@ fn rewrite_macro_inner(
Some(SeparatorTactic::Never)
};
if FORCED_BRACKET_MACROS.contains(macro_name) && !is_nested_macro {
context.inside_macro.replace(false);
context.leave_macro();
if context.use_block_indent() {
force_trailing_comma = Some(SeparatorTactic::Vertical);
};

View File

@ -19,7 +19,7 @@ use crate::source_map::SpanUtils;
use crate::spanned::Spanned;
use crate::utils::{
contains_skip, extra_offset, first_line_width, inner_attributes, last_line_extendable, mk_sp,
ptr_vec_to_ref_vec, semicolon_for_expr, trimmed_last_line_width,
ptr_vec_to_ref_vec, semicolon_for_expr, trimmed_last_line_width, unicode_str_width,
};
/// A simple wrapper type against `ast::Arm`. Used inside `write_list()`.
@ -452,7 +452,9 @@ fn rewrite_match_body(
match rewrite {
Some(ref body_str)
if is_block || (!body_str.contains('\n') && body_str.len() <= body_shape.width) =>
if is_block
|| (!body_str.contains('\n')
&& unicode_str_width(body_str) <= body_shape.width) =>
{
return combine_orig_body(body_str);
}
@ -470,11 +472,6 @@ fn rewrite_match_body(
next_line_body_shape.width,
);
match (orig_body, next_line_body) {
(Some(ref orig_str), Some(ref next_line_str))
if orig_str == next_line_str || context.inside_macro() =>
{
combine_orig_body(orig_str)
}
(Some(ref orig_str), Some(ref next_line_str))
if prefer_next_line(orig_str, next_line_str, RhsTactics::Default) =>
{
@ -575,6 +572,7 @@ fn can_flatten_block_around_this(body: &ast::Expr) -> bool {
| ast::ExprKind::Box(ref expr)
| ast::ExprKind::Try(ref expr)
| ast::ExprKind::Unary(_, ref expr)
| ast::ExprKind::Index(ref expr, _)
| ast::ExprKind::Cast(ref expr, _) => can_flatten_block_around_this(expr),
_ => false,
}

View File

@ -29,7 +29,7 @@ pub(crate) struct RewriteContext<'a> {
pub(crate) parse_session: &'a ParseSess,
pub(crate) source_map: &'a SourceMap,
pub(crate) config: &'a Config,
pub(crate) inside_macro: RefCell<bool>,
pub(crate) inside_macro: Rc<RefCell<bool>>,
// Force block indent style even if we are using visual indent style.
pub(crate) use_block: RefCell<bool>,
// When `is_if_else_block` is true, unindent the comment on top
@ -45,6 +45,23 @@ pub(crate) struct RewriteContext<'a> {
pub(crate) skipped_range: Rc<RefCell<Vec<(usize, usize)>>>,
}
pub(crate) struct InsideMacroGuard {
is_nested_macro_context: bool,
inside_macro_ref: Rc<RefCell<bool>>,
}
impl InsideMacroGuard {
pub(crate) fn is_nested(&self) -> bool {
self.is_nested_macro_context
}
}
impl Drop for InsideMacroGuard {
fn drop(&mut self) {
self.inside_macro_ref.replace(self.is_nested_macro_context);
}
}
impl<'a> RewriteContext<'a> {
pub(crate) fn snippet(&self, span: Span) -> &str {
self.snippet_provider.span_to_snippet(span).unwrap()
@ -63,6 +80,18 @@ impl<'a> RewriteContext<'a> {
*self.inside_macro.borrow()
}
pub(crate) fn enter_macro(&self) -> InsideMacroGuard {
let is_nested_macro_context = self.inside_macro.replace(true);
InsideMacroGuard {
is_nested_macro_context,
inside_macro_ref: self.inside_macro.clone(),
}
}
pub(crate) fn leave_macro(&self) {
self.inside_macro.replace(false);
}
pub(crate) fn is_if_else_block(&self) -> bool {
*self.is_if_else_block.borrow()
}

View File

@ -870,7 +870,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
parse_session: self.parse_session,
source_map: self.source_map,
config: self.config,
inside_macro: RefCell::new(false),
inside_macro: Rc::new(RefCell::new(false)),
use_block: RefCell::new(false),
is_if_else_block: RefCell::new(false),
force_one_line_chain: RefCell::new(false),

View File

@ -549,3 +549,22 @@ fn issue_3005() {
},
}
}
// #3774
fn issue_3774() {
{
{
{
match foo {
Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => unreachab(),
Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => unreacha!(),
Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => unreachabl(),
Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => unreachae!(),
Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => unreachable(),
Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => unreachable!(),
Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => rrunreachable!(),
}
}
}
}
}

View File

@ -574,3 +574,32 @@ fn issue_3005() {
}
}
}
// #3774
fn issue_3774() {
{
{
{
match foo {
Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => unreachab(),
Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => unreacha!(),
Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => {
unreachabl()
}
Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => {
unreachae!()
}
Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => {
unreachable()
}
Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => {
unreachable!()
}
Lam(_, _, _) | Pi(_, _, _) | Let(_, _, _, _) | Embed(_) | Var(_) => {
rrunreachable!()
}
}
}
}
}
}