Release notes
36c4608 (2026-11-06)
New Features
- Rewrite rules can now add
#includedirectives to the files they edit withbronto::include(header). Write the header in angle brackets, as in"<vector>", to get a system include. Any other spelling gives a quoted include. The header can be any constant string expression thatbronto::evalaccepts, including values bound at each rewrite site. Headers that are invalid or can't be evaluated are reported with clear diagnostics. apply,format, and Compiler Explorer mode now insert the headers that rewrites request, following the project's clang-format include style. Existing includes are never re-sorted.- When building with Bazel,
run --includenow looks up the defines and include directories of thecc_libraryproviding each forced-include header and applies them to every translation unit. It also builds any generated headers those libraries need. - Added a "union" strategy for merging fossil records, which succeeds when overlapping edits are identical.
- Added a local MCP server that reports
bronto-refactorprogress to AI agents such as Claude.
Bug Fixes
- A pattern that uses a parameter twice no longer matches arguments that differ only in an operator, member, cast type, or character value. Before, the second argument was silently dropped.
- Fixed crashes when matching fold expressions, const member calls used inside larger expressions, and explicit conversion operator calls.
- Implicit-conversion patterns now match
return p;for pointers and other scalars, and no longer treat direct-initialization such asT x(p)orT x{p}as an implicit conversion. - Fixed
BRONTO_REWRITE_MACROpatterns: fixed identifiers and keywords now match, and literals must match their exact spelling. - Deleting a macro expansion that forms a whole statement now also removes its semicolon.
- Hoisting and statement deletion now add braces wherever they are needed:
inside
switchcases ahead of a later label, under unbracedifand loop bodies, after macros that end a statement, and when deleting calls to empty functions. This prevents code that fails to compile or silently changes behavior. Empty braces replace a bare;where a statement is required. - Empty replacements that are an operand of a comma expression can now be deleted where the result is unaffected.
- Replacement and inlined functions returning
voidthat contain an earlyreturnare now rejected instead of producing incorrect code. Areturninside a lambda no longer counts as an early exit. - Inlining calls with template arguments that aren't written in the source, such
as
S<3>::f()or deduced value parameters, no longer crashes. Unsupported cases are refused with a warning. - Hoisted declarations are now spelled with the types written at the call site, fixing declarations that didn't compile when the pattern named a template parameter through a member.
- Substituted template type, value, and template-template parameters, along with pack expansions, now render correctly in replacements.
- Fixed a crash when rendering nested pack expansions of different lengths.
- Fixed parenthesization that could produce
--1from-f(-1), or drop parentheses in-(m - n)for classes with destructors and for comparisons rewritten throughoperator<=>. - Declaration rewrites whose replacement declares a class-type variable without an initializer now keep the original initializer.
- Separate records inserting text at the same offset, or inside another record's replacement, are now reported as conflicts instead of being combined into invalid code. This fixes chained inlinings.
- Choosing which conflicting edit survives is now consistent from run to run, and conflict reports label insertions correctly.
- Cached results reused with
--temp-dirnow account for force-included headers, so stale results are no longer returned. - In-process formatting with a named style such as
llvmnow uses that style instead of falling back to Google. - The
targetandargumentssettings for Bazel in.brontorcno longer fail with a confusing "unknown variant" error. countno longer accepts and silently ignores--include.- Abseil
ABSL_REFACTOR_INLINEpatterns are recognized reliably again.