Skip to content

Conversation

@tt-a1i
Copy link
Contributor

@tt-a1i tt-a1i commented Dec 14, 2025

Summary

Fixed #8179: useConsistentArrowReturn autofix no longer produces semantically incorrect code when adding braces to arrow functions with multiline expressions.

Problem

When running biome lint --fix with useConsistentArrowReturn configured with style: "always", the autofix could produce code that silently changes runtime behavior:

Input:

const foo = (l: string) =>
  l
    .split('\n')

Before (incorrect autofix):

const foo = (l: string) =>
  {
  return
  l
    .split("\n");
}

The function now returns undefined instead of the split array because JavaScript's automatic semicolon insertion (ASI) inserts a semicolon after return when followed by a newline.

Solution

Strip leading trivia (newlines/whitespace) from the expression before inserting it after the return keyword, ensuring return and the expression stay on the same line.

After (correct autofix):

const foo = (l: string) =>
  {
  return l
    .split("\n");
}

Changes

  • use_consistent_arrow_return.rs: Added trim_leading_trivia() call on the expression
  • Added test cases for multiline expressions

AI Assistance Disclosure

This PR was written with assistance from Claude Code.

…cted code

When adding braces to arrow functions with multiline expressions,
the autofix previously preserved leading trivia (newlines) from the
original expression. This could place a newline between `return` and
the expression, triggering JavaScript's automatic semicolon insertion
and causing the function to return `undefined` instead of the value.

Fixed by trimming leading trivia from the expression before inserting
it after the `return` keyword.

Fixes biomejs#8179
@changeset-bot
Copy link

changeset-bot bot commented Dec 14, 2025

🦋 Changeset detected

Latest commit: e4bc3f2

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 13 packages
Name Type
@biomejs/biome Patch
@biomejs/cli-win32-x64 Patch
@biomejs/cli-win32-arm64 Patch
@biomejs/cli-darwin-x64 Patch
@biomejs/cli-darwin-arm64 Patch
@biomejs/cli-linux-x64 Patch
@biomejs/cli-linux-arm64 Patch
@biomejs/cli-linux-x64-musl Patch
@biomejs/cli-linux-arm64-musl Patch
@biomejs/wasm-web Patch
@biomejs/wasm-bundler Patch
@biomejs/wasm-nodejs Patch
@biomejs/backend-jsonrpc Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added A-Linter Area: linter L-JavaScript Language: JavaScript and super languages labels Dec 14, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 14, 2025

Walkthrough

This PR fixes a critical bug in the useConsistentArrowReturn rule's autofix where adding braces to arrow functions inadvertently inserted a newline between return and the expression. This triggered JavaScript's automatic semicolon insertion (ASI), causing functions to return undefined instead of their intended values. The fix trims leading trivia from the expression before constructing the return statement to prevent this issue. Test cases are added to validate handling of multiline expressions.

Possibly related PRs

Suggested labels

A-Linter, L-JavaScript

Suggested reviewers

  • arendjr
  • siketyan
  • ematipico

Pre-merge checks and finishing touches

✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main fix: preventing useConsistentArrowReturn from producing code affected by automatic semicolon insertion.
Description check ✅ Passed The description clearly explains the bug, the problem with ASI, the solution (trimming leading trivia), and the expected output.
Linked Issues check ✅ Passed The PR addresses all requirements from issue #8179: fixing the autofix to not produce ASI-affected code, ensuring correct semantics, and adding test cases for multiline expressions.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the useConsistentArrowReturn autofix issue—the rule implementation, changeset entry, and test cases are all relevant.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
crates/biome_js_analyze/src/lint/nursery/use_consistent_arrow_return.rs (1)

182-186: Good fix: trim leading trivia to avoid return + newline ASI traps.

This looks like the right surgical move: trim_leading_trivia() ensures the returned expression starts immediately after return , preserving runtime semantics for multiline arrow bodies. Nice.
Consider adding a one-liner to the rule rustdoc noting the autofix avoids ASI pitfalls for multiline expressions (since this is a behavioural fix). As per coding guidelines, ...

.changeset/fix-use-consistent-arrow-return-asi.md (1)

1-5: Changeset: please add a tiny before/after code example for the rule.

Guidelines for .changeset/*.md ask for a code example; a minimal () =>\n foo.bar()() => { return foo.bar(); } style snippet would make this much easier to grok at release-note speed. As per coding guidelines, ...

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a392c06 and e4bc3f2.

⛔ Files ignored due to path filters (1)
  • crates/biome_js_analyze/tests/specs/nursery/useConsistentArrowReturn/always.invalid.js.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (3)
  • .changeset/fix-use-consistent-arrow-return-asi.md (1 hunks)
  • crates/biome_js_analyze/src/lint/nursery/use_consistent_arrow_return.rs (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useConsistentArrowReturn/always.invalid.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
.changeset/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Write changesets that are concise (1-3 sentences), user-focused, use past tense for actions taken and present tense for Biome behavior, include code examples for rules, and end sentences with periods

Files:

  • .changeset/fix-use-consistent-arrow-return-asi.md
crates/**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Update inline rustdoc documentation for rules, assists, and their options when adding new features or changing existing features in Rust crates

Files:

  • crates/biome_js_analyze/src/lint/nursery/use_consistent_arrow_return.rs
🧠 Learnings (12)
📓 Common learnings
Learnt from: arendjr
Repo: biomejs/biome PR: 7593
File: crates/biome_service/src/workspace/server.rs:1306-1306
Timestamp: 2025-09-25T12:32:59.003Z
Learning: In the biomejs/biome project, do not flag compilation errors during code review as they are handled by the existing test infrastructure and CI. Focus on other code quality aspects instead.
📚 Learning: 2025-12-12T10:11:05.549Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-12T10:11:05.549Z
Learning: Applies to .changeset/*.md : Write changesets that are concise (1-3 sentences), user-focused, use past tense for actions taken and present tense for Biome behavior, include code examples for rules, and end sentences with periods

Applied to files:

  • .changeset/fix-use-consistent-arrow-return-asi.md
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `useConsistent` prefix for rules that ensure consistency across the codebase (e.g., `useConsistentArrayType`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_consistent_arrow_return.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `useShorthand` prefix for rules that report syntax rewritable using equivalent compact syntax (e.g., `useShorthandAssign`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_consistent_arrow_return.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noEmpty` prefix for rules that report empty code (e.g., `noEmptyBlockStatements`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_consistent_arrow_return.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUseless` prefix for rules that report unnecessary code that could be removed or simplified (e.g., `noUselessConstructor`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_consistent_arrow_return.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUnused` prefix for rules that report unused entities (e.g., `noUnusedVariables`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_consistent_arrow_return.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noRedundant` prefix for rules that report redundant code (e.g., `noRedundantUseStrict`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_consistent_arrow_return.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : When navigating CST nodes that return `Result`, use the try operator `?` to convert to `Option`, or use `let else` pattern for `Vec` return types in rule run functions

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_consistent_arrow_return.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUndeclared` prefix for rules that report undefined entities (e.g., `noUndeclaredVariables`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_consistent_arrow_return.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noConstant` prefix for rules that report computations always evaluated to the same value (e.g., `noConstantMathMinMaxClamp`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_consistent_arrow_return.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Framework-specific rules should be named using the `use` or `no` prefix followed by the framework name (e.g., `noVueReservedProps`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_consistent_arrow_return.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Test Node.js API
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Documentation
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: End-to-end tests
  • GitHub Check: Check Dependencies
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: autofix
🔇 Additional comments (1)
crates/biome_js_analyze/tests/specs/nursery/useConsistentArrowReturn/always.invalid.js (1)

5-13: Solid regression coverage for the ASI edge case.

Both examples force the “expression begins on the next line” shape that used to break semantics under --fix.

@codspeed-hq
Copy link

codspeed-hq bot commented Dec 14, 2025

CodSpeed Performance Report

Merging #8440 will not alter performance

Comparing tt-a1i:fix/use-consistent-arrow-return-asi (e4bc3f2) with main (a78774b)1

Summary

✅ 58 untouched
⏩ 95 skipped2

Footnotes

  1. No successful run was found on main (a392c06) during the generation of this report, so a78774b was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

  2. 95 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@dyc3
Copy link
Contributor

dyc3 commented Dec 14, 2025

This is a duplicate of #8183

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Linter Area: linter L-JavaScript Language: JavaScript and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 useConsistentArrowReturn autofix produces semantically incorrect code (returns undefined)

2 participants