diff --git a/src/expr.rs b/src/expr.rs index f68f6322f..545b43dfd 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1036,6 +1036,16 @@ impl IdentFragment for Member { } } +#[cfg(any(feature = "parsing", feature = "printing"))] +impl Member { + pub(crate) fn is_named(&self) -> bool { + match self { + Member::Named(_) => true, + Member::Unnamed(_) => false, + } + } +} + ast_struct! { /// The index of an unnamed tuple struct field. #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] @@ -3021,15 +3031,6 @@ pub(crate) mod parsing { Ok(!trailing_dot) } - impl Member { - pub(crate) fn is_named(&self) -> bool { - match self { - Member::Named(_) => true, - Member::Unnamed(_) => false, - } - } - } - #[cfg(feature = "full")] #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] impl Parse for PointerMutability { @@ -3405,22 +3406,17 @@ pub(crate) mod printing { fn print_expr_call(e: &ExprCall, tokens: &mut TokenStream, fixup: FixupContext) { outer_attrs_to_tokens(&e.attrs, tokens); - let call_precedence = if let Expr::Field(_) = &*e.func { - Precedence::MIN - } else { - Precedence::Unambiguous - }; let func_fixup = fixup.leftmost_subexpression_with_begin_operator( #[cfg(feature = "full")] true, false, ); - print_subexpression( - &e.func, - func_fixup.leading_precedence(&e.func) < call_precedence, - tokens, - func_fixup, - ); + let needs_group = if let Expr::Field(func) = &*e.func { + func.member.is_named() + } else { + func_fixup.leading_precedence(&e.func) < Precedence::Unambiguous + }; + print_subexpression(&e.func, needs_group, tokens, func_fixup); e.paren_token.surround(tokens, |tokens| { e.args.to_tokens(tokens); diff --git a/tests/test_expr.rs b/tests/test_expr.rs index 6dd876221..03ebd1db6 100644 --- a/tests/test_expr.rs +++ b/tests/test_expr.rs @@ -703,6 +703,7 @@ fn test_fixup() { quote! { (1 < 2) == (3 < 4) }, quote! { { (let _ = ()) } }, quote! { (#[attr] thing).field }, + quote! { (self.f)() }, ] { let original: Expr = syn::parse2(tokens).unwrap();