llvm / llvm/llvm-project

[clang-format] BeforeLambdaBody causes incorrect argument wrapping when lambda is not the last argument

Open
#182,274 1 comment 0 reactions 0 assignees View on GitHub
clang-format
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

## Description

When `BraceWrapping.BeforeLambdaBody` is `true` and a function call contains a lambda that is **not the last argument** (either followed by more arguments, or when multiple lambdas are present), arguments before the lambda are incorrectly wrapped to a new line even though they fit on the first line.

## Steps to Reproduce

Use the following `.clang-format` configuration:

```yaml
BasedOnStyle: LLVM
BreakBeforeBraces: Custom
BraceWrapping:
BeforeLambdaBody: true
AllowShortLambdasOnASingleLine: None
```

Format the following code:

```cpp
void test() {
func(a, b, [](int x) { return x; }, c);
}
```

## Expected Output

```cpp
void test() {
func(a, b,
[](int x)
{
return x;
},
c);
}
```

Arguments `a, b,` should stay on the same line as the function name.

## Actual Output

```cpp
void test() {
func(
a, b,
[](int x)
{
return x;
},
c);
}
```

Arguments `a, b,` are incorrectly wrapped to a new line, with a line break inserted right after the opening `(`.

## Root Cause

The `DisallowLineBreaks` heuristic in `ContinuationIndenter::addTokenOnCurrentLine` scans ahead for lambda braces and sets `State.NoLineBreak = true` when found. This heuristic is designed for inlined lambda bodies: when all arguments including the lambda should stay on the same line. However, with `BeforeLambdaBody`, the lambda body is intentionally expanded using Allman-style braces, so this heuristic should not apply — the multi-line lambda body is expected and should not trigger argument wrapping.

The issue manifests when:
- A lambda argument is followed by another argument (trailing argument after lambda)
- Multiple lambda arguments are present in the same function call

## Fix

Return `false` from the `DisallowLineBreaks` lambda when `BraceWrapping.BeforeLambdaBody` is `true`, since Allman-style lambda formatting makes the heuristic counterproductive. I can provide a PR with fix + unit tests.

## Environment

- LLVM version: 21.1.8 (and likely older versions since `BeforeLambdaBody` was introduced)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.