Skip to content

chore(deps): upgrade sugar_path to v3#10230

Merged
graphite-app[bot] merged 1 commit into
mainfrom
chore/upgrade-sugar-path-3
Jul 12, 2026
Merged

chore(deps): upgrade sugar_path to v3#10230
graphite-app[bot] merged 1 commit into
mainfrom
chore/upgrade-sugar-path-3

Conversation

@hyfdev

@hyfdev hyfdev commented Jul 12, 2026

Copy link
Copy Markdown
Member

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:

  • relativeCow<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 — 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

  • cargo check --workspace --all-targets
  • cargo test -p rolldown_std_utils
  • cargo test -p rolldown_utils stabilize_id
  • cargo test -p rolldown_common stabilize
  • cargo clippy on touched crates with -D warnings
  • CI full matrix

Related

@netlify

netlify Bot commented Jul 12, 2026

Copy link
Copy Markdown

Deploy Preview for rolldown-rs canceled.

Name Link
🔨 Latest commit 9d0c7b4
🔍 Latest deploy log https://app.netlify.com/projects/rolldown-rs/deploys/6a539e70790a8f00084d431d

@socket-security

socket-security Bot commented Jul 12, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatedcargo/​sugar_path@​2.0.1 ⏵ 3.0.098 -110093 -3100100

View full report

@hyfdev
hyfdev marked this pull request as ready for review July 12, 2026 07:57
Copilot AI review requested due to automatic review settings July 12, 2026 07:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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_path to v3 and adapt call sites to the new relative -> Cow<Path> and strict slash conversion APIs.
  • Add/propagate rolldown_std_utils helpers (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.

Comment thread crates/rolldown/src/hmr/hmr_stage.rs Outdated
Comment thread crates/rolldown_plugin/src/plugin_driver/mod.rs Outdated
Comment thread crates/rolldown_std_utils/src/path_ext.rs Outdated
@codspeed-hq

codspeed-hq Bot commented Jul 12, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 7 untouched benchmarks
⏩ 10 skipped benchmarks1


Comparing chore/upgrade-sugar-path-3 (648ce29) with main (1c14bb3)

Open in CodSpeed

Footnotes

  1. 10 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.

Comment thread crates/rolldown_common/src/file_emitter.rs Outdated
Comment thread crates/rolldown_plugin_vite_dynamic_import_vars/src/ast_visit.rs Outdated

hyfdev commented Jul 12, 2026

Copy link
Copy Markdown
Member Author

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
@graphite-app
graphite-app Bot force-pushed the chore/upgrade-sugar-path-3 branch from 648ce29 to 9d0c7b4 Compare July 12, 2026 14:02
@graphite-app
graphite-app Bot merged commit 9d0c7b4 into main Jul 12, 2026
33 of 34 checks passed
@graphite-app
graphite-app Bot deleted the chore/upgrade-sugar-path-3 branch July 12, 2026 14:06
@rolldown-guard rolldown-guard Bot mentioned this pull request Jul 15, 2026
shulaoda added a commit that referenced this pull request Jul 15, 2026
## [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]>
graphite-app Bot pushed a commit that referenced this pull request Jul 17, 2026
## 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
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.

3 participants