@@ -1879,19 +1879,10 @@ void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs)
18791879 if (! hgs.errorMsg)
18801880 tf.attributesApply(&printAttribute);
18811881
1882- CompoundStatement cs = f.fbody.isCompoundStatement();
1883- Statement s1;
1884- if (f.semanticRun >= PASS .semantic3done && cs)
1885- {
1886- s1 = (* cs.statements)[cs.statements.length - 1 ];
1887- }
1888- else
1889- s1 = ! cs ? f.fbody : null ;
1890- ReturnStatement rs = s1 ? s1.endsWithReturnStatement() : null ;
1891- if (rs && rs.exp)
1882+ if (auto result = arrowFuncLiteralResult(f))
18921883 {
18931884 buf.put(" => " );
1894- rs.exp .expressionToBuffer(buf, hgs);
1885+ result .expressionToBuffer(buf, hgs);
18951886 }
18961887 else
18971888 {
@@ -3863,6 +3854,28 @@ private void expressionToBuffer(Expression e, ref OutBuffer buf, ref HdrGenState
38633854 expressionPrettyPrint(e, buf, hgs);
38643855}
38653856
3857+ /* *************************************************
3858+ * Returns the expression result if `f` is printed with `=>` syntax, otherwise `null`.
3859+ *
3860+ * Arrow function literals have an AssignExpression body, so they bind less tightly
3861+ * than postfix operators and must be parenthesized when used as a call callee etc.
3862+ */
3863+ private Expression arrowFuncLiteralResult (FuncLiteralDeclaration f)
3864+ {
3865+ if (! f.fbody)
3866+ return null ;
3867+
3868+ CompoundStatement cs = f.fbody.isCompoundStatement();
3869+ Statement s1;
3870+ if (f.semanticRun >= PASS .semantic3done && cs)
3871+ s1 = (* cs.statements)[cs.statements.length - 1 ];
3872+ else
3873+ s1 = ! cs ? f.fbody : null ;
3874+
3875+ ReturnStatement rs = s1 ? s1.endsWithReturnStatement() : null ;
3876+ return rs && rs.exp ? rs.exp : null ;
3877+ }
3878+
38663879// to be called if e could be loweredFrom another expression instead of acessing precedence[e.op] directly
38673880private PREC expPrecedence (ref HdrGenState hgs, Expression e)
38683881{
@@ -3877,6 +3890,13 @@ private PREC expPrecedence(ref HdrGenState hgs, Expression e)
38773890 if (ne.loweredFrom)
38783891 e = ne.loweredFrom;
38793892 }
3893+ // https://github.com/dlang/dmd/issues/23326
3894+ // Arrow lambdas are not true primaries; treat like assign-level expressions for paren insertion.
3895+ if (auto fe = e.isFuncExp())
3896+ {
3897+ if (fe.fd && arrowFuncLiteralResult(fe.fd))
3898+ return PREC .assign;
3899+ }
38803900 return precedence[e.op];
38813901}
38823902
0 commit comments