Turbopack: turbofmt/turbobail macros#90092
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
Merging this PR will not alter performance
Comparing Footnotes
|
9eb6ebb to
208506a
Compare
Tests Passed |
Stats from current PR✅ No significant changes detected📊 All Metrics📖 Metrics GlossaryDev Server Metrics:
Build Metrics:
Change Thresholds:
⚡ Dev Server
📦 Dev Server (Webpack) (Legacy)📦 Dev Server (Webpack)
⚡ Production Builds
📦 Production Builds (Webpack) (Legacy)📦 Production Builds (Webpack)
📦 Bundle SizesBundle Sizes⚡ TurbopackClient Main Bundles: **401 kB** → **401 kB** ✅ -30 B80 files with content-based hashes (individual files not comparable between builds) Server Middleware
Build DetailsBuild Manifests
📦 WebpackClient Main Bundles
Polyfills
Pages
Server Edge SSR
Middleware
Build DetailsBuild Manifests
Build Cache
🔄 Shared (bundler-independent)Runtimes
📎 Tarball URL |
f3a0484 to
2b20af3
Compare
turbopack/crates/turbo-tasks-backend/tests/derive_value_to_string.rs
Outdated
Show resolved
Hide resolved
| } | ||
| RealPathResultError::NotFound => { | ||
| format!("Symlink {orig} is invalid, it points at a file that doesn't exist") | ||
| turbofmt!("Symlink {orig} is invalid, it points at a file that doesn't exist") |
There was a problem hiding this comment.
so here we are actually changing the error message to include the filesystem name.... since these are always about actual filesystem paths... does that make sense
| // Happens if the link is to a non-existent file | ||
| FileSystemEntryType::NotFound => DirectoryEntry::Error( | ||
| format!("Symlink {symlink} points at {real_path} which does not exist").into(), | ||
| turbofmt!("Symlink {symlink} points at {real_path} which does not exist") |
There was a problem hiding this comment.
I think all of the other errors in this file are using fs-prefixed paths, but I can revert this one if it makes sense (I suspect it just add consistency)
| path | ||
| } else { | ||
| bail!("chunk path {chunk_path} is not in output root {output_root}"); | ||
| turbobail!("chunk path {chunk_path} is not in output root {output_root}"); |
There was a problem hiding this comment.
not sure it is correct to change this
21d8d31 to
d70683c
Compare
3aa4fc8 to
13e9892
Compare
# What
Add turbofmt! and turbobail! proc macros for async string formatting
with Vc<T> and ResolvedVc<T> values.
A new, agent-friendly `FORMATTING.md` file is added to help agents
figure out how these macros work.
# Why
Formatting strings that include turbo-tasks values currently requires
manually .await?ing each Vc, then calling format!, then converting to
RcStr via .into(). By using macros, we can reduce a lot of boilerplate
and potentially offer some opportunities for optimizations by reducing
intermediate, throwaway tasks.
# How
We make use of the "auto-deref" pattern in Rust to choose the "best"
formatting option: ValueToString or Display.
- Zero-alloc FormatIter: A shared iterator parser over format strings
(RawString, EscapedBrace, VarRef, VarRefFormat) that both macros and the
derive use, replacing duplicated manual parsing.
- Borrow-based capture: turbofmt! uses async { .. } (not async move), so
non-Copy types like FileSystemPath can be used in multiple turbofmt!
calls without cloning.
- Debug on StringifyType: Enables {:?} format specs in turbofmt!.
- Converted ~30 call sites across next-core, turbo-tasks-fs,
turbopack-core, turbopack-ecmascript, and others.
# What's Left
- Constants cannot be formatted with turbofmt! yet because of arcane
Rust hygiene rules (similar issue to
rust-lang/rust#131446)
- rust-analyzer doesn't show these format strings as "real" format
strings yet because of limitations of the analyzer, but this should be
possible to make work.
- Automatic derive for ValueToStringRef to avoid intermediate tasks in a
few places where formatting is trivial
- turbowrite!/turbowriteln! could clean up a bit more code

What
Add turbofmt! and turbobail! proc macros for async string formatting with Vc and ResolvedVc values.
A new, agent-friendly
FORMATTING.mdfile is added to help agents figure out how these macros work.Why
Formatting strings that include turbo-tasks values currently requires manually .await?ing each Vc, then calling format!, then converting to RcStr via .into(). By using macros, we can reduce a lot of boilerplate and potentially offer some opportunities for optimizations by reducing intermediate, throwaway tasks.
How
We make use of the "auto-deref" pattern in Rust to choose the "best" formatting option: ValueToString or Display.
What's Left
assert_eq!is not 100% hygienic rust-lang/rust#131446)