diff --git a/src/closures.rs b/src/closures.rs index 2ec31afa391..7fdc0e85686 100644 --- a/src/closures.rs +++ b/src/closures.rs @@ -170,7 +170,7 @@ fn allow_multi_line(expr: &ast::Expr) -> bool { // When rewriting closure's body without block, we require it to fit in a single line // unless it is a block-like expression or we are inside macro call. - let veto_multiline = (!allow_multi_line(expr) && !context.inside_macro) + let veto_multiline = (!allow_multi_line(expr) && !context.inside_macro()) || context.config.force_multiline_blocks(); expr.rewrite(context, shape) .and_then(|rw| { @@ -370,7 +370,7 @@ pub fn args_have_many_closure(args: &[&T]) -> bool fn is_block_closure_forced(context: &RewriteContext, expr: &ast::Expr) -> bool { // If we are inside macro, we do not want to add or remove block from closure body. - if context.inside_macro { + if context.inside_macro() { false } else { is_block_closure_forced_inner(expr) diff --git a/src/expr.rs b/src/expr.rs index 9aafd71dd22..10f2cd2aba7 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -474,7 +474,7 @@ pub fn rewrite_array( separator: ",", trailing_separator: if trailing_comma { SeparatorTactic::Always - } else if context.inside_macro && !exprs.is_empty() { + } else if context.inside_macro() && !exprs.is_empty() { let ends_with_bracket = context.snippet(span).ends_with(']'); let bracket_offset = if ends_with_bracket { 1 } else { 0 }; let snippet = context.snippet(mk_sp(span.lo(), span.hi() - BytePos(bracket_offset))); @@ -656,7 +656,7 @@ pub fn rewrite_block_with_visitor( let mut visitor = FmtVisitor::from_context(context); visitor.block_indent = shape.indent; - visitor.is_if_else_block = context.is_if_else_block; + visitor.is_if_else_block = context.is_if_else_block(); match block.rules { ast::BlockCheckMode::Unsafe(..) => { let snippet = context.snippet(block.span); @@ -1142,10 +1142,13 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option { width: block_width, ..shape }; - let mut block_context = context.clone(); - block_context.is_if_else_block = self.else_block.is_some(); - let block_str = - rewrite_block_with_visitor(&block_context, "", self.block, None, block_shape, true)?; + let block_str = { + let old_val = context.is_if_else_block.replace(self.else_block.is_some()); + let result = + rewrite_block_with_visitor(context, "", self.block, None, block_shape, true); + context.is_if_else_block.replace(old_val); + result? + }; let mut result = format!("{}{}", cond_str, block_str); @@ -1456,7 +1459,7 @@ pub fn rewrite_call( shape, span, context.config.width_heuristics().fn_call_width, - if context.inside_macro { + if context.inside_macro() { if span_ends_with_comma(context, span) { Some(SeparatorTactic::Always) } else { @@ -1768,7 +1771,7 @@ enum StructLitField<'a> { let nested_shape = shape_for_tactic(tactic, h_shape, v_shape); let ends_with_comma = span_ends_with_comma(context, span); - let force_no_trailing_comma = if context.inside_macro && !ends_with_comma { + let force_no_trailing_comma = if context.inside_macro() && !ends_with_comma { true } else { false @@ -1947,7 +1950,7 @@ pub fn rewrite_tuple<'a, T>( debug!("rewrite_tuple {:?}", shape); if context.use_block_indent() { // We use the same rule as function calls for rewriting tuples. - let force_tactic = if context.inside_macro { + let force_tactic = if context.inside_macro() { if span_ends_with_comma(context, span) { Some(SeparatorTactic::Always) } else { diff --git a/src/macros.rs b/src/macros.rs index 9c2b77e5c39..b3f443a628e 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -152,11 +152,22 @@ pub fn rewrite_macro( shape: Shape, position: MacroPosition, ) -> Option { - let context = &mut context.clone(); - context.inside_macro = true; + context.inside_macro.replace(true); + let result = rewrite_macro_inner(mac, extra_ident, context, shape, position); + context.inside_macro.replace(false); + result +} + +pub fn rewrite_macro_inner( + mac: &ast::Mac, + extra_ident: Option, + context: &RewriteContext, + shape: Shape, + position: MacroPosition, +) -> Option { if context.config.use_try_shorthand() { if let Some(expr) = convert_try_mac(mac, context) { - context.inside_macro = false; + context.inside_macro.replace(false); return expr.rewrite(context, shape); } } @@ -295,7 +306,7 @@ pub fn rewrite_macro( // then we can rewrite this as an usual array literal. // Otherwise, we must preserve the original existence of trailing comma. if FORCED_BRACKET_MACROS.contains(¯o_name.as_str()) { - context.inside_macro = false; + context.inside_macro.replace(false); trailing_comma = false; } // Convert `MacroArg` into `ast::Expr`, as `rewrite_array` only accepts the latter. diff --git a/src/overflow.rs b/src/overflow.rs index c76b67c461e..79f93899fa3 100644 --- a/src/overflow.rs +++ b/src/overflow.rs @@ -384,7 +384,7 @@ fn wrap_items(&self, items_str: &str, shape: Shape, is_extendable: bool) -> Stri result.push_str(self.ident); result.push_str(self.prefix); if !self.context.use_block_indent() - || (self.context.inside_macro && !items_str.contains('\n') && fits_one_line) + || (self.context.inside_macro() && !items_str.contains('\n') && fits_one_line) || (is_extendable && extend_width <= shape.width) { if self.context.config.spaces_within_parens_and_brackets() && !items_str.is_empty() { diff --git a/src/patterns.rs b/src/patterns.rs index cfff023bafc..44e32462a8d 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -360,10 +360,6 @@ fn rewrite_tuple_pat( // add comma if `(x,)` let add_comma = path_str.is_none() && pat_vec.len() == 1 && dotdot_pos.is_none(); - let mut context = context.clone(); - if let Some(&TuplePatField::Dotdot(..)) = pat_vec.last() { - context.inside_macro = true; - } let path_str = path_str.unwrap_or_default(); let mut pat_ref_vec = Vec::with_capacity(pat_vec.len()); for pat in pat_vec { diff --git a/src/rewrite.rs b/src/rewrite.rs index 01671227e39..7eb8c18bbe6 100644 --- a/src/rewrite.rs +++ b/src/rewrite.rs @@ -29,12 +29,12 @@ pub struct RewriteContext<'a> { pub parse_session: &'a ParseSess, pub codemap: &'a CodeMap, pub config: &'a Config, - pub inside_macro: bool, + pub inside_macro: RefCell, // Force block indent style even if we are using visual indent style. pub use_block: RefCell, // When `format_if_else_cond_comment` is true, unindent the comment on top // of the `else` or `else if`. - pub is_if_else_block: bool, + pub is_if_else_block: RefCell, // When rewriting chain, veto going multi line except the last element pub force_one_line_chain: RefCell, pub snippet_provider: &'a SnippetProvider<'a>, @@ -53,4 +53,12 @@ pub fn use_block_indent(&self) -> bool { pub fn budget(&self, used_width: usize) -> usize { self.config.max_width().checked_sub(used_width).unwrap_or(0) } + + pub fn inside_macro(&self) -> bool { + *self.inside_macro.borrow() + } + + pub fn is_if_else_block(&self) -> bool { + *self.is_if_else_block.borrow() + } } diff --git a/src/visitor.rs b/src/visitor.rs index 54a85062d43..22f892d4fb4 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -696,9 +696,9 @@ pub fn get_context(&self) -> RewriteContext { parse_session: self.parse_session, codemap: self.codemap, config: self.config, - inside_macro: false, + inside_macro: RefCell::new(false), use_block: RefCell::new(false), - is_if_else_block: false, + is_if_else_block: RefCell::new(false), force_one_line_chain: RefCell::new(false), snippet_provider: self.snippet_provider, }