From 0e5c5686503d7ef41b344c2464e35e6329ed75f1 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 29 Nov 2024 12:56:45 -0800 Subject: [PATCH 1/3] Add test of parentheses needed in call of field ---- test_fixup stdout ---- thread 'test_fixup' panicked at tests/test_expr.rs:717:9: original: (self . f) () reconstructed: self . f () --- tests/test_expr.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_expr.rs b/tests/test_expr.rs index 6dd876221d..03ebd1db65 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(); From 48d0101557047df08ca7859ab8c5eae9cb6c0805 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 29 Nov 2024 13:00:49 -0800 Subject: [PATCH 2/3] Fix parenthesization of field expressions in function calls --- src/expr.rs | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/expr.rs b/src/expr.rs index f68f6322fe..84e1e98956 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -3405,22 +3405,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(_) = &*e.func { + true + } 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); From 1445ccf5866dadeabcbd05f4d1bd3543298c1e2d Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 29 Nov 2024 13:33:04 -0800 Subject: [PATCH 3/3] Do not parenthesize unnamed tuple struct fields in call --- src/expr.rs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/expr.rs b/src/expr.rs index 84e1e98956..545b43dfd7 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 { @@ -3410,8 +3411,8 @@ pub(crate) mod printing { true, false, ); - let needs_group = if let Expr::Field(_) = &*e.func { - true + let needs_group = if let Expr::Field(func) = &*e.func { + func.member.is_named() } else { func_fixup.leading_precedence(&e.func) < Precedence::Unambiguous };