Skip to content

docs: waproto::codec pinned codec module, -9.1% binary size (whatsapp-rust#842) - #314

Closed
jlucaso1 wants to merge 3 commits into
mainfrom
claude/eager-cerf-9mavv3
Closed

jlucaso1 wants to merge 3 commits into
mainfrom
claude/eager-cerf-9mavv3

Conversation

@jlucaso1

@jlucaso1 jlucaso1 commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Adds changelog/2026-06-11-proto-codec-pinning.mdx documenting the new waproto::codec module introduced in oxidezap/whatsapp-rust#842
  • Updates docs.json to include the new entry at the top of the changelog list

What changed in the source PR

PR #842 added a waproto::codec module with #[inline(never)] non-generic wrapper functions for the hottest protobuf roots (Message, WebMessageInfo, HistorySync, MessageContextInfo). This pins a single codegen instantiation in the waproto crate and eliminates duplicate copies that fat LTO cannot merge, reducing the release binary .text section by −1,208 KiB (−9.1%). Field-number constants in wacore::messages were also migrated from hardcoded literals to generated waproto::tags::* constants. No user-facing behavioral or API breaking changes.

Test plan

  • Verify changelog entry renders correctly in the Mintlify preview
  • Confirm docs.json entry slug matches the file name exactly

Generated by Claude Code


Summary by cubic

Adds a changelog entry for waproto::codec, which pins non-generic protobuf codec entry points and reduces the release binary by ~1.2 MiB (−9.1%). Updates docs.json and clarifies that .proto field rename/removal (not renumber) triggers compile-time failures via waproto::tags.

Written for commit 29b3b0f. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Documentation
    • Added changelog entry documenting binary size optimization improvements in the release build.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@mintlify

mintlify Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
whatsapp-rust 🟢 Ready View Preview Jun 11, 2026, 7:07 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds a changelog entry documenting the waproto::codec pinned protobuf codec module, which uses non-generic #[inline(never)] entry points to eliminate duplicate protobuf encode/decode monomorphizations. The documentation notes a reported ~1.2 MiB binary size reduction and the shift to sourcing field-number constants from waproto::tags::* with compile-time safety. The new changelog page is registered in docs.json navigation.

Changes

Protobuf codec pinning changelog

Layer / File(s) Summary
Changelog entry and navigation
changelog/2026-06-11-proto-codec-pinning.mdx, docs.json
Added new changelog document describing waproto::codec, its non-generic pinned entry points eliminating codegen duplication (~1.2 MiB reduction), and the sourcing of field constants from waproto::tags::* with compile-time field-renumber validation; registered the page in navigation.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~2 minutes

Possibly related PRs

  • oxidezap/whatsapp-rust-docs#309: Both PRs document the same schema-pinned protobuf wire-tag constants generated in waproto::tags and their usage for field-number correctness.

Poem

🐰 A codec so pinned, no duplication in sight,
Monomorphs collapse to make binaries light,
Tags guide the path where field numbers reside,
Safe, additive changes, the protobuf's pride! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately reflects the main change: documentation of the waproto::codec module with the binary size reduction benefit, and includes the related upstream PR reference.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/eager-cerf-9mavv3

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
changelog/2026-06-11-proto-codec-pinning.mdx (3)

10-10: ⚡ Quick win

Break this sentence into multiple sentences — one idea per sentence.

This 170-word sentence contains at least six distinct ideas: the audit tool and settings, the duplicate monomorphization finding, prost's generic implementation, the instantiation-per-crate behavior, the LTO merge limitation, and the specific example of Message::encode_raw duplication. As per coding guidelines, documentation should keep sentences concise with one idea per sentence.

📝 Suggested rewrite
-A `cargo-bloat` audit of the release binary (fat LTO, `codegen-units=1`) found that 2.5 MiB of the 13.1 MiB `.text` section was duplicate monomorphization. Because prost's `Message` methods are generic, rustc instantiates them in every crate that calls them, and each crate's copy carries a distinct instantiating-crate symbol hash that LTO cannot merge. `whatsapp::Message::encode_raw` alone appeared as three full copies at ~160 KiB each; the decode side split further by buffer type.
+A `cargo-bloat` audit of the release binary (fat LTO, `codegen-units=1`) found that 2.5 MiB of the 13.1 MiB `.text` section was duplicate monomorphization. Prost's `Message` methods are generic, so rustc instantiates them in every crate that calls them. Each crate's copy carries a distinct instantiating-crate symbol hash that LTO cannot merge. For example, `whatsapp::Message::encode_raw` alone appeared as three full copies at ~160 KiB each. The decode side split further by buffer type.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@changelog/2026-06-11-proto-codec-pinning.mdx` at line 10, Split the long
sentence into multiple concise sentences so each idea stands alone: mention the
audit tool and settings (cargo-bloat, fat LTO, codegen-units=1) in one sentence,
state the finding of duplicate monomorphization in another, describe that
prost's generic Message methods cause per-crate instantiation in a separate
sentence, note that rustc instantiates them per crate and LTO cannot merge
distinct symbol hashes as its own sentence, and finally give the specific
example about whatsapp::Message::encode_raw appearing as three ~160 KiB copies
(and the decode-side splitting by buffer type) as a separate concluding
sentence; ensure references to prost, Message, and whatsapp::Message::encode_raw
remain intact for clarity.

Source: Coding guidelines


26-26: ⚡ Quick win

Break this sentence into multiple sentences — one idea per sentence.

This sentence contains four distinct ideas: the #[inline(never)] attribute's purpose, MIR inlining prevention, the buffer shape standardization, and the instantiation consequence. As per coding guidelines, documentation should keep sentences concise with one idea per sentence.

📝 Suggested rewrite
-The `#[inline(never)]` attribute prevents MIR inlining from re-expanding the bodies at call sites, which would silently reintroduce per-crate copies. All decode helpers take `&[u8]` and use `&mut &[u8]` internally — the single buffer shape already instantiated across the workspace — so no second buffer-type tree is created.
+The `#[inline(never)]` attribute prevents MIR inlining from re-expanding the bodies at call sites. Without this attribute, rustc would silently reintroduce per-crate copies. All decode helpers take `&[u8]` and use `&mut &[u8]` internally. This single buffer shape is already instantiated across the workspace, so no second buffer-type tree is created.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@changelog/2026-06-11-proto-codec-pinning.mdx` at line 26, Split the long
sentence into multiple concise sentences so each idea is separate: state that
the `#[inline(never)]` attribute prevents MIR inlining; explain that preventing
MIR inlining stops re-expansion of function bodies at call sites (which would
otherwise silently reintroduce per-crate copies); note that all decode helpers
accept `&[u8]` and operate using `&mut &[u8]` internally; and conclude that
because the helpers share the single buffer shape across the workspace, no
second buffer-type tree is created. Ensure `#[inline(never)]`, MIR inlining,
`&[u8]`, and `&mut &[u8]` are mentioned to preserve the original technical
points.

Source: Coding guidelines


12-40: 💤 Low value

Consider using active voice with second person ("you") throughout the changelog entry.

The documentation currently uses third person ("All production call sites," "Existing code calling") instead of the second person active voice recommended by the coding guidelines. While the current style is acceptable for changelog entries, you could make it more engaging by addressing the reader directly where appropriate.

As per coding guidelines: "Use active voice and second person ('you') in documentation."

Example of more direct phrasing

For line 40:

-`waproto::codec` is additive. Existing code calling prost's `Message` trait methods directly continues to compile; the new functions are an alternative, not a replacement, for downstream crates.
+`waproto::codec` is additive. Your existing code calling prost's `Message` trait methods directly continues to compile. You can use the new functions as an alternative; they are not a replacement.

Note: Changelog entries often use a more neutral, third-person style, so this suggestion is optional.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@changelog/2026-06-11-proto-codec-pinning.mdx` around lines 12 - 40, Rewrite
the changelog entry to use active voice and second-person phrasing throughout:
replace passive/third-person sentences like "All production call sites in
`wacore` and the main crate now route through `#[inline(never)]` wrappers" with
direct instructions such as "You should route production call sites in `wacore`
and the main crate through the `#[inline(never)]` wrappers (e.g.
`message_encoded_len`, `message_encode_into`, `message_decode`, etc.)" and
change "Existing code calling prost's `Message` trait methods directly continues
to compile" to "If you call prost's `Message` trait methods directly, your code
will continue to compile." Apply similar conversions for other lines mentioning
`waproto::codec`, `Message::encode_raw`, and `waproto::tags::*` so the reader is
addressed as "you" and actions are stated in active voice.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@changelog/2026-06-11-proto-codec-pinning.mdx`:
- Line 10: Split the long sentence into multiple concise sentences so each idea
stands alone: mention the audit tool and settings (cargo-bloat, fat LTO,
codegen-units=1) in one sentence, state the finding of duplicate
monomorphization in another, describe that prost's generic Message methods cause
per-crate instantiation in a separate sentence, note that rustc instantiates
them per crate and LTO cannot merge distinct symbol hashes as its own sentence,
and finally give the specific example about whatsapp::Message::encode_raw
appearing as three ~160 KiB copies (and the decode-side splitting by buffer
type) as a separate concluding sentence; ensure references to prost, Message,
and whatsapp::Message::encode_raw remain intact for clarity.
- Line 26: Split the long sentence into multiple concise sentences so each idea
is separate: state that the `#[inline(never)]` attribute prevents MIR inlining;
explain that preventing MIR inlining stops re-expansion of function bodies at
call sites (which would otherwise silently reintroduce per-crate copies); note
that all decode helpers accept `&[u8]` and operate using `&mut &[u8]`
internally; and conclude that because the helpers share the single buffer shape
across the workspace, no second buffer-type tree is created. Ensure
`#[inline(never)]`, MIR inlining, `&[u8]`, and `&mut &[u8]` are mentioned to
preserve the original technical points.
- Around line 12-40: Rewrite the changelog entry to use active voice and
second-person phrasing throughout: replace passive/third-person sentences like
"All production call sites in `wacore` and the main crate now route through
`#[inline(never)]` wrappers" with direct instructions such as "You should route
production call sites in `wacore` and the main crate through the
`#[inline(never)]` wrappers (e.g. `message_encoded_len`, `message_encode_into`,
`message_decode`, etc.)" and change "Existing code calling prost's `Message`
trait methods directly continues to compile" to "If you call prost's `Message`
trait methods directly, your code will continue to compile." Apply similar
conversions for other lines mentioning `waproto::codec`, `Message::encode_raw`,
and `waproto::tags::*` so the reader is addressed as "you" and actions are
stated in active voice.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3b06ac27-c3ee-4f26-b309-cc37aec92d22

📥 Commits

Reviewing files that changed from the base of the PR and between 5e04c00 and 8afd49a.

📒 Files selected for processing (2)
  • changelog/2026-06-11-proto-codec-pinning.mdx
  • docs.json

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 issue found across 2 files

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread changelog/2026-06-11-proto-codec-pinning.mdx Outdated
A field rename/removal breaks compilation via waproto::tags, not a renumber
(which silently propagates the new value through generated constants).

Identified by cubic review on #314.

https://claude.ai/code/session_0144MtqbnA996hhwFmjNSfzn
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants