chore(deps): upgrade sugar_path to v3#10230
Conversation
✅ Deploy Preview for rolldown-rs canceled.
|
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Pull request overview
Upgrades the workspace dependency on sugar_path to v3 and migrates affected call sites, while centralizing Rolldown’s “known UTF-8 path → slash string” compositions into rolldown_std_utils to make the intended (fast, strict) usage easy to follow across the codebase.
Changes:
- Upgrade
sugar_pathto v3 and adapt call sites to the newrelative -> Cow<Path>and strict slash conversion APIs. - Add/propagate
rolldown_std_utilshelpers (relative_path_to_slash,relative_path_as_js_specifier,path_buf_to_slash, etc.) and switch hot/important path composition call sites to use them. - Document preferred path manipulation patterns and anti-patterns in internal docs and cross-link from module-id docs.
Reviewed changes
Copilot reviewed 35 out of 36 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| internal-docs/path-manipulation/style-guide.md | New style guide documenting preferred helper usage and anti-patterns. |
| internal-docs/module-id/implementation.md | Updates module-id doc to point at the new helpers + style guide. |
| crates/rolldown/tests/integration/test262.rs | Adapts relative() call site to Cow<Path> by owning where needed. |
| crates/rolldown/src/utils/process_code_and_sourcemap.rs | Uses relative_path_to_slash for Windows sourcemap source normalization. |
| crates/rolldown/src/types/scan_stage_cache.rs | Updates to_slash() usage for sugar_path v3 strict API. |
| crates/rolldown/src/stages/generate_stage/mod.rs | Replaces open-coded relative+slash chains with std_utils helpers. |
| crates/rolldown/src/module_loader/external_module_task.rs | Centralizes relative+slash string generation via std_utils helpers. |
| crates/rolldown/src/hmr/hmr_stage.rs | Updates strict to_slash() usage for watched file paths. |
| crates/rolldown_utils/src/stabilize_id.rs | Switches to absolute_path_to_relative_slash helper for absolute-path stabilization. |
| crates/rolldown_std_utils/src/path_ext.rs | Adds new path composition helpers and updates expect_to_slash to sugar_path v3 API. |
| crates/rolldown_std_utils/src/lib.rs | Re-exports new path helper APIs. |
| crates/rolldown_std_utils/Cargo.toml | Adds sugar_path dependency for the new helper implementations. |
| crates/rolldown_plugin/src/plugin_driver/mod.rs | Updates strict to_slash() usage for transform dependencies. |
| crates/rolldown_plugin_vite_resolve/src/vite_resolve_plugin.rs | Uses path_buf_to_slash helper for strict, owned slash conversion. |
| crates/rolldown_plugin_vite_reporter/src/lib.rs | Uses relative_path_to_slash helper for reporting output dir prefix. |
| crates/rolldown_plugin_vite_reporter/Cargo.toml | Adds dependency on rolldown_std_utils. |
| crates/rolldown_plugin_vite_import_glob/src/utils.rs | Uses relative_path_to_slash helper for import-glob path formatting. |
| crates/rolldown_plugin_vite_import_glob/Cargo.toml | Adds dependency on rolldown_std_utils. |
| crates/rolldown_plugin_vite_dynamic_import_vars/src/lib.rs | Uses relative_path_to_slash helper for dynamic import var normalization. |
| crates/rolldown_plugin_vite_dynamic_import_vars/src/ast_visit.rs | Uses relative_path_to_slash helper for normalized glob pattern generation. |
| crates/rolldown_plugin_vite_dynamic_import_vars/Cargo.toml | Adds dependency on rolldown_std_utils. |
| crates/rolldown_plugin_copy_module/src/lib.rs | Replaces custom JS-specifier logic with relative_path_as_js_specifier. |
| crates/rolldown_plugin_copy_module/Cargo.toml | Adds rolldown_std_utils, removes direct sugar_path. |
| crates/rolldown_plugin_bundle_analyzer/src/lib.rs | Uses relative_path_to_slash for stable absolute-id formatting. |
| crates/rolldown_plugin_bundle_analyzer/Cargo.toml | Adds rolldown_std_utils, removes direct sugar_path. |
| crates/rolldown_plugin_asset_module/src/lib.rs | Replaces custom JS-specifier logic with relative_path_as_js_specifier. |
| crates/rolldown_plugin_asset_module/Cargo.toml | Adds rolldown_std_utils, removes direct sugar_path. |
| crates/rolldown_error/src/types/diagnostic_options.rs | Uses relative_path_to_slash for stable diagnostics path formatting. |
| crates/rolldown_error/Cargo.toml | Adds rolldown_std_utils, removes direct sugar_path. |
| crates/rolldown_common/src/types/stable_module_id.rs | Uses relative_path_to_slash for stable module id formatting. |
| crates/rolldown_common/src/types/module_id.rs | Adapts relative() to return PathBuf by calling into_owned(). |
| crates/rolldown_common/src/module/external_module.rs | Replaces hand-rolled JS-specifier logic with relative_path_as_js_specifier. |
| crates/rolldown_common/src/file_emitter.rs | Uses path_buf_to_slash helper for strict slash conversion after normalization. |
| crates/rolldown_common/src/chunk/mod.rs | Uses std_utils helpers for relative path generation and slash conversion. |
| Cargo.toml | Bumps workspace sugar_path dependency version to 3. |
| Cargo.lock | Locks sugar_path to 3.0.0 and reflects new std_utils deps. |
Merging this PR will not alter performance
Comparing Footnotes
|
Merge activity
|
## Summary Upgrade workspace `sugar_path` from **2.0.1 → 3.0.0**, migrate every call site that broke, and centralize Rolldown's known-UTF-8 path compositions so the “right” usage is hard to miss. ### Why sugar_path 3 helps Rolldown sugar_path 3 is the breaking redesign aimed at Rolldown-shaped work: - **`relative` → `Cow<Path>`**: clean descendant paths can return a borrowed suffix with **zero result allocation** (the package-sideEffects-style shape was about **19–21% faster** in same-machine microbenches vs the old owned-`PathBuf` API; not a whole-build claim). - **Strict / consuming slash conversion**: `into_slash` can reuse an owned `PathBuf` buffer for the final UTF-8 `String` (one allocation for the final container). - **Owned cwd reuse**: `absolutize_with(cwd.join(out_dir))` can grow the joined buffer instead of cloning after normalize (already how Rolldown calls it). - **Windows**: relative calculation no longer allocates slash-normalized copies just to compare clean native paths. Rolldown already enables `cached_current_dir`; that stays. Those wins only show up if call sites use the intended composition. Open-coding `relative(...).to_slash_lossy().into_owned()` or `relative(...).as_path().expect_to_slash()` leaves performance on the table and fights the 3.0 API. ### API migration (compile / contract) - `relative` returns `Cow<Path>` → `.into_owned()` where a `PathBuf` is required - `to_slash()` is strict (no `Option`) → drop `.unwrap()` / `.map_or_else` - Equal paths → empty relative path; call sites that need `.` / `./` keep that policy via helpers - `absolutize_with(cwd.join(out_dir))` already passes owned cwd (no change needed) ### Prevent wrong usage next time 1. **Helpers** in `rolldown_std_utils` (`relative_path_to_slash`, `relative_path_as_js_specifier`, `path_buf_to_slash`, …) with unit tests — hot call sites use these. 2. **Style guide**: [`internal-docs/path-manipulation/style-guide.md`](https://github.com/rolldown/rolldown/blob/chore/upgrade-sugar-path-3/internal-docs/path-manipulation/style-guide.md) — domain assumptions, preferred helpers, anti-patterns, PR checklist. Linked from `internal-docs/module-id/implementation.md`. **Guidance for future code:** if you need “path relative to X as a `/` string for a module id / import / diagnostic”, use `rolldown_std_utils` first. Do not reintroduce `to_slash_lossy` on known-UTF-8 module paths. ### Intentionally left as direct sugar_path / lossy Simple display conversions that are not a relative→String composition (import-glob bases, package.json realpath, some cwd display). Those are not the measured hot composition. ## Test plan - [x] `cargo check --workspace --all-targets` - [x] `cargo test -p rolldown_std_utils` - [x] `cargo test -p rolldown_utils stabilize_id` - [x] `cargo test -p rolldown_common stabilize` - [x] `cargo clippy` on touched crates with `-D warnings` - [ ] CI full matrix ## Related - sugar_path 3.0.0: https://crates.io/crates/sugar_path/3.0.0 - sugar_path redesign: hyfdev/sugar_path#40
648ce29 to
9d0c7b4
Compare
## [1.2.0] - 2026-07-15 ### 🚀 Features - dev: skip shipping factories for newly imported top-level modules (#10223) by @h-a-n-a - dev: per-client ship map for HMR patch sizing (#10208) by @h-a-n-a - dev: client-side HMR (#10164) by @h-a-n-a - dev: send a full-reload update to clients when a tsconfig changes (#10262) by @shulaoda - treat `import.meta['url']` and `import.meta['ROLLUP_FILE_URL_*']` as side-effect free (#10267) by @sapphi-red - rewrite `import.meta['url']` (#10251) by @sapphi-red - add `FILE_NOT_FOUND` error (#10220) by @sapphi-red - treat `import.meta.ROLLUP_FILE_URL_*` as side-effect free (#10217) by @sapphi-red ### 🐛 Bug Fixes - sourcemap: preserve unmapped boundaries during composition (#10254) by @hyfdev - `[format]` in `*FileNames` option for ESM format should be `es` instead of `esm` (#10214) by @sapphi-red - sourcemap: preserve coarse mappings during composition (#10249) by @hyfdev - rolldown_plugin_vite_import_glob: support tsconfig paths with `import.meta.glob` (#10167) by @sapphi-red - dev: clear tsconfig caches for bare full builds (#10276) by @shulaoda - dev: force a full rebuild when a tsconfig changes (#10261) by @shulaoda - treat rooted drive-less module ids as absolute in preserveModules naming (#10235) by @IWANABETHATGUY - watch: rebuild when tsconfig files change (#10258) by @shulaoda - watch: drop tsconfig-merged transform options on each rebuild (#10257) by @shulaoda - incorrect `EMPTY_IMPORT_META` warning for `import.meta.ROLLUP_FILE_URL_*` for CJS output (#10221) by @sapphi-red - deconflict: rename CJS locals shadowing wrapped-ESM namespace objects (#9970) by @IWANABETHATGUY - rolldown: drop the unused runtime module after entry-level external flattening (#10237) by @IWANABETHATGUY - rolldown: re-propagate has_dynamic_exports to transitive star importers (#10239) by @IWANABETHATGUY - tree-shaking: tree-shake destructured dynamic import namespace bindings (#10213) by @logaretm - s390x: use json-escape-simd 3.1.1 for big-endian JSON escaping fix (#10211) by @satyamg1620 ### 🚜 Refactor - dev: move full-reload to client side (#10207) by @h-a-n-a - readability follow-ups to the ReplaceWith migration (#10286) by @IWANABETHATGUY - replace take_in-then-write-back with ReplaceWith and by-value moves (#10285) by @Boshen - share the main resolver's cache with the transformer's tsconfig lookups (#10205) by @shulaoda - rolldown: extract the ns star-external __reExport emission rule into LinkingMetadata (#10238) by @IWANABETHATGUY - rolldown: unify link/generate diagnostics into a Diagnostics accumulator (#10234) by @IWANABETHATGUY - sourcemap_filenames: drop dead sourcemap-filename plumbing (#10189) by @IWANABETHATGUY - extract external import symbol merging into a method (#10224) by @IWANABETHATGUY - rolldown: skip CJS namespace merging under strict execution order (#10203) by @hyfdev - resolve the manual tsconfig per file instead of once at startup (#10200) by @shulaoda - rolldown: route interop ESM init emission through a shared init-target view (#10202) by @hyfdev - rolldown: collapse vestigial wrap-kind state and share chunk sort helper (#10201) by @hyfdev ### 📚 Documentation - show plugin kinds in JSDoc and each hook's description (#10218) by @sapphi-red - add an explanation about removing imports from external modules without any messages (#10215) by @sapphi-red ### ⚡ Performance - sourcemap: owned merge in SourceJoiner::join (4005->5 allocs/chunk) (#10250) by @Boshen - avoid redundant sourcemap string copies in collapse and minify paths (#10093) by @Boshen ### 🧪 Testing - code-splitting: establish strict-order review baselines (#10287) by @hyfdev - dev: add hot API test cases (#10181) by @h-a-n-a - code-splitting: normalize strict execution order variants (#10277) by @hyfdev - code-splitting: harden strict execution order coverage (#10252) by @hyfdev - code-splitting: add strict execution order regressions (#10253) by @hyfdev ### ⚙️ Miscellaneous Tasks - deps: update github actions (#10241) by @renovate[bot] - deps: update oxc to 0.140.0 (#10274) by @shulaoda - update Yunfei's GitHub username (#10275) by @hyfdev - deps: update napi (#10260) by @renovate[bot] - deps: update test262 submodule for tests (#10266) by @rolldown-guard[bot] - deps: update dependency vite-plus to v0.2.4 (#10256) by @renovate[bot] - deps: update napi (#10240) by @renovate[bot] - deps: update oxc resolver to v11.24.2 (#10245) by @renovate[bot] - deps: update rust crates (#10244) by @renovate[bot] - disable Renovate updates for idna_adapter (#10248) by @shulaoda - deps: update oxc resolver to v11.24.1 (#10232) by @renovate[bot] - deps: update rust crate oxc_sourcemap to v8.1.1 (#10233) by @renovate[bot] - deps: update dependency rolldown-plugin-dts to ^0.27.0 (#10206) by @renovate[bot] - deps: upgrade sugar_path to v3 (#10230) by @hyfdev - add `dist-*` to `.gitignore` in sourcemap-filenames/hash-final-content fixture (#10216) by @sapphi-red - deps: update dependency rust to v1.97.0 (#10209) by @renovate[bot] ### ❤️ New Contributors * @satyamg1620 made their first contribution in [#10211](#10211) Co-authored-by: shulaoda <[email protected]>
## Summary - consume joined `PathBuf` values through a shared `normalize_path_buf_to_slash` helper - avoid copying the normalized glob path into a second allocation before matching - strengthen the `./foo` versus `foo` regression test through the public filter path, including a Windows drive cwd - document the owned-path rule in the path manipulation guide and link it from `AGENTS.md` ## Why #10313 correctly inserted lexical normalization into the existing `join -> to_string_lossy -> slash` chain. However, `join` had already produced an owned `PathBuf`; calling the non-consuming `normalize()` API converted it to `Cow<Path>`, and the following string conversion copied the normalized buffer. The same ownership issue was caught during #10230's review in `file_emitter.rs`, but the general rule never made it into the final style guide. The guide covered consuming relative/slash conversion and exposed `path_buf_to_slash`, but it did not provide a named normalize-plus-slash helper or list the non-consuming owned-path chain as an anti-pattern. This PR records that missing rule and centralizes the composition so future call sites do not need to reconstruct it. ## Performance A release-mode `GlobalAlloc` counter around matcher construction reported one fewer allocation/reallocation for each non-bypass relative glob: | Pattern | Current | This PR | | --- | ---: | ---: | | `foo/*.txt` | 3 | 2 | | `./foo/*.txt` | 4 | 3 | The probe compared exact outputs across clean, dirty, parent, trailing-separator, absolute, and `**` cases. No benchmark case is added here; if this path is added to continuous performance coverage, the benchmark should land first in a baseline-only PR and the implementation comparison should follow from that baseline. ## Validation - `just lint-rust` - `just lint-repo` - `cargo test -p rolldown_std_utils -p rolldown_utils -p rolldown_common` - `cargo check -p rolldown_std_utils -p rolldown_utils --tests --target x86_64-pc-windows-msvc --locked` - `cargo check -p rolldown_std_utils --tests --target wasm32-wasip1 --locked` - `RUSTDOCFLAGS='-D warnings' cargo doc -p rolldown_std_utils --no-deps --locked` - `just test-rust` executed the workspace suite successfully until the single `test262_module_code` test stopped on the intentionally uninitialized `test262` submodule; 1,873 integration tests had passed, with no code failure - adversarial review passed after documenting the strict UTF-8 panic contract
Summary
Upgrade workspace
sugar_pathfrom 2.0.1 → 3.0.0, migrate every call site that broke, and centralize Rolldown's known-UTF-8 path compositions so the “right” usage is hard to miss.Why sugar_path 3 helps Rolldown
sugar_path 3 is the breaking redesign aimed at Rolldown-shaped work:
relative→Cow<Path>: clean descendant paths can return a borrowed suffix with zero result allocation (the package-sideEffects-style shape was about 19–21% faster in same-machine microbenches vs the old owned-PathBufAPI; not a whole-build claim).into_slashcan reuse an ownedPathBufbuffer for the final UTF-8String(one allocation for the final container).absolutize_with(cwd.join(out_dir))can grow the joined buffer instead of cloning after normalize (already how Rolldown calls it).Rolldown already enables
cached_current_dir; that stays.Those wins only show up if call sites use the intended composition. Open-coding
relative(...).to_slash_lossy().into_owned()orrelative(...).as_path().expect_to_slash()leaves performance on the table and fights the 3.0 API.API migration (compile / contract)
relativereturnsCow<Path>→.into_owned()where aPathBufis requiredto_slash()is strict (noOption) → drop.unwrap()/.map_or_else././keep that policy via helpersabsolutize_with(cwd.join(out_dir))already passes owned cwd (no change needed)Prevent wrong usage next time
rolldown_std_utils(relative_path_to_slash,relative_path_as_js_specifier,path_buf_to_slash, …) with unit tests — hot call sites use these.internal-docs/path-manipulation/style-guide.md— domain assumptions, preferred helpers, anti-patterns, PR checklist. Linked frominternal-docs/module-id/implementation.md.Guidance for future code: if you need “path relative to X as a
/string for a module id / import / diagnostic”, userolldown_std_utilsfirst. Do not reintroduceto_slash_lossyon known-UTF-8 module paths.Intentionally left as direct sugar_path / lossy
Simple display conversions that are not a relative→String composition (import-glob bases, package.json realpath, some cwd display). Those are not the measured hot composition.
Test plan
cargo check --workspace --all-targetscargo test -p rolldown_std_utilscargo test -p rolldown_utils stabilize_idcargo test -p rolldown_common stabilizecargo clippyon touched crates with-D warningsRelated