Skip to content

feat!: redesign path APIs for borrowing and owned reuse#40

Merged
hyfdev merged 2 commits into
mainfrom
work
Jul 12, 2026
Merged

feat!: redesign path APIs for borrowing and owned reuse#40
hyfdev merged 2 commits into
mainfrom
work

Conversation

@hyfdev

@hyfdev hyfdev commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary

  • seal and redesign SugarPath around borrowed Path/str, explicit cwd, and strict, fallible, or explicitly lossy Unicode conversion
  • add a sealed SugarPathBuf surface only for consuming operations that measurably reuse owned storage
  • make relative return Cow<Path> and borrow canonical host-native descendant suffixes without allocating
  • remove the common descendant result allocation from a Rolldown-shaped package-sideEffects operation; earlier same-machine Criterion runs measured that representative operation about 19-21% faster than the previous public API, without implying a whole-build gain
  • align lexical Unix and Windows behavior across trailing separators, drives, UNC and namespace roots, drive-relative and root-relative context, verbatim paths, and invalid native encoding
  • validate allocation contracts with native macOS, Linux, and Windows snapshots; retain scoped same-machine macOS timing evidence and report the current cross-CPU CodSpeed comparison separately

Performance

Same-machine Criterion measurements used an Apple M3 Pro with cached_current_dir. They were recorded during branch development against a saved pre-redesign public-API checkpoint, before PR #41 established the accepted main baseline. They are valid same-host microbenchmark evidence for the representative cases below, but they are not a timing comparison between 9e6b627 and 59877db and are not CodSpeed evidence. The package-sideEffects branch counts come from a pinned Rolldown trace; the timing rows use representative 96-byte descendant and 135-byte upward fixtures.

Workload Before After Change alloc / realloc Scope
package-sideEffects, weighted 4,888 descendant : 2 upward 88.71 ns 70.13–71.70 ns 19.2–20.9% faster 4,890 / 0 → 2 / 0 Derived result-buffer calls for the observed branch mix; not a whole-build result
descendant representative 88.70 ns 70.12–71.69 ns 19.2–20.9% faster 1 / 0 → 0 / 0 Final result borrows the target suffix
upward representative control 111.32 ns 97.51–102.82 ns 7.6–12.4% faster 1 / 0 → 1 / 0 An owned result is still required
ARM64 long-prefix absolute-path relative scalar scan NEON scan 7.8–22.6% faster unchanged Four significant shapes; short-prefix and dotted controls unchanged, one noisy shape excluded

The weighted allocation row is a derived Unix result-buffer model: the previous public API allocated a result PathBuf on every call, while the final API borrows each descendant and allocates only the two upward results. It is a 99.96% reduction in result-buffer allocation calls for that observed branch mix, not a measurement of whole-build allocations. Against the saved already-borrowing Cow prototype rather than the previous public API, the final weighted implementation is still about 10–12% faster.

These are representative SugarPath microbenchmarks, not a claim that an entire Rolldown build is 19–21% faster. Rolldown is not changed in this PR, still needs to migrate to the new API after the breaking release, and has no end-to-end build timing for this change yet. The ARM64 short-prefix and dotted controls are unchanged; different_subtrees was noisy and is not counted as a win.

Accepted baseline comparison

PR #41 established the accepted pre-change baseline at 9e6b627. This PR is rebuilt directly on that commit, with the same stable benchmark identities and ordered allocation scenarios plus one final-only owned-cwd row.

All GitHub Actions tests, native allocation checks, and the CodSpeed simulation and memory execution jobs pass. The external CodSpeed analysis reports 52 improvements, 18 regressions, 146 unchanged rows, and 30 skipped historical rows, but it also flags different runtime environments: the baseline CPU Simulation ran on AMD EPYC 7763, while the PR CPU Simulation ran on Intel Xeon Platinum 8573C. Those counts are included for transparency, but the 18 CPU deltas are not treated as confirmed regressions and are not used to support the speedup claims above. A same-CPU hot-path follow-up is tracked separately.

The allocation conclusions do not depend on that cross-CPU timing comparison. Committed native snapshots on macOS ARM64, Linux GNU x86_64, and Windows MSVC x86_64 verify the final allocation and reallocation counts in both default and Rolldown configurations.

Why

Rolldown is SugarPath's main consumer. A trace of the pinned ThreeJS and Rome builds recorded 19,518 relative calls. The aggregate borrowable-descendant rate was 4,888 of 19,518 (25.04%), but caller attribution changes the decision: the package-sideEffects caller produced all 4,888 hits and only two upward misses. StableModuleId, stabilize_id, and sourcemap calls were all upward; the first ends in ArcStr, while the latter two end in String.

That evidence supports one borrowing relative API plus ordinary consuming composition. It does not support separate public relative_cow or fused relative-to-string methods.

Public API

SugarPath is now sealed and implemented directly for Path and str. PathBuf, String, and string wrappers retain method syntax through deref lookup, while generic T: SugarPath bounds and UFCS on wrappers must use the underlying Path or str:

  • normalize
  • absolutize, try_absolutize, absolutize_with
  • relative, try_relative, relative_with
  • to_slash, try_to_slash, to_slash_lossy
  • as_path

SugarPathBuf is sealed and implemented only for PathBuf:

  • into_normalized
  • into_slash
  • try_into_slash
  • into_slash_lossy

relative now returns Cow<Path>. to_slash and into_slash are strict; the try_* forms preserve failure without replacement, and only explicitly named *_lossy methods replace invalid encoding. try_into_slash returns the original PathBuf on failure. Explicit-cwd methods accept borrowed or owned values directly, and an owned PathBuf can supply the result buffer.

Semantics

  • Path parsing is host-native and lexical; no filesystem or symlink lookup is performed.
  • normalize preserves one trailing separator; relative strips the target trailing separator and returns an empty path for equal inputs.
  • Ambient cwd is read only when required. try_* exposes lookup errors; ordinary methods document their panic contract.
  • Windows drive and component comparison is ASCII-insensitive while the input spelling of a drive letter is preserved.
  • When a relative spelling cannot cross drives, UNC shares, or namespaces, the normalized target is returned instead of fabricating a relation.
  • Drive-relative and root-relative inputs retain or cancel unknown context only when that result is provable from the inputs.
  • Under a Windows verbatim prefix, / remains a literal component character. Components that cannot be represented as a standalone native relative path fall back to the normalized target without changing their meaning.
  • Full Unix invalid-byte and Windows invalid-wide paths are preserved outside explicit Unicode conversion.

Node is the reference for host-native lexical behavior where its output is a valid native path relation. SugarPath deliberately differs for ordinary Windows UNC paths with the same server and different shares: server + share is the root, so it returns the normalized absolute target rather than a spelling that remains inside the original share.

Final allocation contracts

Native snapshots on macOS ARM64, Linux GNU x64, and Windows MSVC x64 verify the same clean-path allocation counts in both default and Rolldown configurations:

Final operation alloc realloc Result
canonical descendant relative -> Cow<Path> 0 0 borrows the receiver suffix
descendant relative -> Cow::into_owned PathBuf 1 0 allocates only the requested final PathBuf
descendant relative(...).into_owned().into_slash() -> String 1 0 allocates only the final String buffer
upward relative(...).into_owned().into_slash() -> String 1 0 reuses the owned relative result as the final String
clean PathBuf::into_normalized 0 0 reuses the input buffer
valid-Unicode PathBuf::into_slash 0 0 reuses the input buffer
clean relative input + owned cwd through absolutize_with 0 1 reuses and grows the cwd buffer; setup excluded

All rows also have zero alloc_zeroed calls. Requested bytes are target- and path-shape-specific, so allocation calls and reallocations are the cross-platform contract.

The ordinary Windows descendant fast path compares native prefixes and components without allocating normalized copies. Its bounded representability guard reads only the first two result bytes and does not add another target/base scan.

A caller-side strip_prefix pre-check did not produce a stable descendant advantage and made the recorded upward misses about 70–80% slower, so the generic API keeps one shared scan.

Validation

  • formatting
  • default and all-feature workspace tests and doctests
  • Clippy over all workspace targets and features with warnings denied
  • rustdoc with warnings denied
  • all benchmark targets compiled
  • package verification
  • native macOS default and Rolldown allocation snapshots
  • native Linux GNU and Windows MSVC allocation snapshot gates
  • native Windows default and all-feature semantic tests
  • Windows GNU and MSVC cross-compilation checks
  • CodSpeed simulation and memory jobs
  • external CodSpeed analysis reviewed with the cross-CPU environment caveat described above

No Docker, Wine, or container-backed Windows command was run for this revision.

Review guide

PR #41 landed the accepted pre-change baseline at 9e6b627. This PR is rebuilt directly on that baseline and now contains two commits:

  1. e639516feat!: redesign path APIs for borrowing and owned reuse
  2. 59877dbbench: record final allocation results

Review the first commit for the public API, implementation, semantics, tests, README, changelog, and PCR records. Review the second for the final native allocation snapshots and their generation records. Superseded compatibility and prototype detours are absent from the rebuilt branch history.

Follow-up

Rolldown source migration remains separate until this breaking SugarPath release lands. Its known-UTF-8 package-sideEffects, stable ID, and sourcemap call sites should then move to the final API while preserving empty-relative handling.

Native Windows timing remains the only platform-specific performance evidence gap; native Windows correctness and allocation behavior are continuously checked.

@codspeed-hq

codspeed-hq Bot commented Jul 11, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 76.87%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 52 improved benchmarks
❌ 18 regressed benchmarks
✅ 146 untouched benchmarks
⏩ 30 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation borrowed_receiver/pathbuf_result 1.9 µs 2.5 µs -24.47%
Simulation relative/borrowed_receiver/pathbuf_result/rolldown_shapes[short_common_prefix] 2.3 µs 3 µs -22.02%
Simulation relative/borrowed_receiver/natural_result/rolldown_shapes[short_common_prefix] 2.3 µs 2.9 µs -21.15%
Simulation relative/borrowed_receiver/pathbuf_result/rolldown_shapes[module_to_cwd] 2.2 µs 2.8 µs -19.38%
Simulation relative/borrowed_receiver/pathbuf_result/rolldown_shapes[different_subtrees] 2.8 µs 3.5 µs -19.02%
Simulation same_path 1.9 µs 2.3 µs -18.3%
Simulation relative/borrowed_receiver/natural_result/rolldown_shapes[different_subtrees] 2.8 µs 3.5 µs -18.26%
Simulation relative/borrowed_receiver/pathbuf_result/rolldown_shapes[same_directory] 2.5 µs 3 µs -18.03%
Simulation normalize/leading_parent_prescan[dirty_late_80b] 3.2 µs 3.9 µs -17.22%
Simulation normalize/leading_parent_prescan[dirty_early_67b] 2.7 µs 3.2 µs -15.51%
Simulation relative/borrowed_receiver/pathbuf_result/rolldown_shapes[deep_siblings] 3.5 µs 4.1 µs -15.09%
Simulation relative/borrowed_receiver/natural_result/rolldown_shapes[deep_siblings] 3.5 µs 4.1 µs -14.41%
Simulation path_receiver/pathbuf_result 2.4 µs 2.8 µs -13.03%
Simulation relative/borrowed_receiver/natural_result/rolldown_shapes[relative_p99_depth_unequal_parents] 11.7 µs 13.3 µs -11.48%
Simulation relative/borrowed_receiver/pathbuf_result/rolldown_shapes[relative_p99_depth_unequal_parents] 11.8 µs 13.3 µs -11.48%
Simulation str_receiver/pathbuf_result 2.4 µs 2.7 µs -11.12%
Simulation relative/borrowed_receiver/pathbuf_result/rolldown_shapes[dot_slow_path] 4.4 µs 4.9 µs -10.27%
Simulation relative/borrowed_receiver/natural_result/rolldown_shapes[dot_slow_path] 4.4 µs 4.9 µs -10.21%
Memory relative/borrowed_receiver/natural_result/rolldown_shapes[relative_p99_depth_siblings] 211 B 18 B ×12
Memory relative/borrowed_receiver/pathbuf_result/rolldown_shapes[relative_p99_depth_siblings] 211 B 18 B ×12
... ... ... ... ... ...

ℹ️ Only the first 20 benchmarks are displayed. Go to the app to view all benchmarks.

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing work (59877db) with main (9e6b627)

Open in CodSpeed

Footnotes

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

@hyfdev hyfdev left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Summary

This umbrella PR is a carefully layered set of allocation-aware path APIs (relative_cow, relative_to_slash_lossy, sealed SugarPathBuf) plus lexical relative, Windows root/UNC fixes, normalization determinism, and an ARM64 NEON common-prefix scan. Core algorithms look correct under the stated contracts; residual risks are release-surface completeness and the still-open absolutize_with owned-base allocation hole.

Issue counts by severity

  • bugs: 0
  • suggestions: 3
  • nits: 1

All findings are posted as inline comments (including ones anchored to the nearest line still present in the diff).

Comment thread CHANGELOG.md
Comment thread Cargo.toml
Comment thread src/sugar_path.rs Outdated
Comment thread src/impl_sugar_path.rs Outdated
@hyfdev hyfdev changed the title feat: add allocation-aware path APIs for Rolldown workloads feat!: redesign path APIs for borrowing and owned reuse Jul 11, 2026
@hyfdev
hyfdev marked this pull request as ready for review July 12, 2026 06:20
Copilot AI review requested due to automatic review settings July 12, 2026 06:20
@hyfdev
hyfdev merged commit 6cce331 into main Jul 12, 2026
13 of 14 checks passed
@github-actions github-actions Bot mentioned this pull request Jul 12, 2026

Copilot AI 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.

Pull request overview

This PR delivers a breaking redesign of SugarPath’s public API to center on borrowed Path/str receivers, explicit current-directory handling, and explicit Unicode conversion policy (strict vs fallible vs lossy), while adding a separate sealed consuming surface (SugarPathBuf) for PathBuf operations that can reuse owned storage. It also substantially expands cross-platform correctness, allocation-contract, and composition tests, and updates the benchmark + allocation snapshot evidence to match the new borrowing/ownership model.

Changes:

  • Redesign SugarPath as a sealed extension trait for Path and str, with relative returning Cow<Path> and new try_* ambient-cwd variants plus explicit-cwd _with methods.
  • Introduce SugarPathBuf (sealed, PathBuf-only) for consuming operations that can reuse allocations (into_normalized, into_slash*).
  • Add/expand integration tests and benchmark/snapshot documentation to validate borrowing, encoding policy, cwd behavior, Windows root semantics, and allocation counts.

Reviewed changes

Copilot reviewed 48 out of 48 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/to_slash.rs Updates slash-conversion tests to assert borrowing/owning behavior and strict vs lossy outputs.
tests/relative.rs Updates and significantly extends relative-path tests, especially Windows root/namespace matrix.
tests/relative_without_cwd.rs Adds a unix-only child-process test ensuring cwd-independent relative paths don’t read cwd.
tests/relative_to_slash.rs Adds tests ensuring composed relative(...).into_owned().into_slash() matches strict composition expectations.
tests/relative_simd.rs Adds NEON boundary tests for aarch64 common-prefix SIMD scanning.
tests/relative_lexical.rs Adds broad lexical relative matrix tests for cwd-(in)dependence and deep-path behavior.
tests/relative_borrowing.rs Adds tests validating when relative can borrow from the target’s storage.
tests/path_identity.rs Adds idempotence and exact-spelling identity tests for normalization across platforms.
tests/owned_api.rs Adds tests for SugarPathBuf allocation reuse and strict/fallible/lossy owned conversions.
tests/invalid_encoding.rs Adds cross-platform invalid-encoding coverage for normalize/relative/absolutize and slash conversions.
tests/deep_paths.rs Refines deep-path tests to better cover borrowed fast paths and SmallVec spill execution paths.
tests/cached_current_dir.rs Adds tests validating cached_current_dir behavior and when caching is (not) used.
tests/as_path.rs Expands as_path tests to confirm deref-based str impl works for string-like wrappers.
tests/absolutize.rs Updates absolutize tests to the redesigned API and adds Cow-contract checks for absolute inputs.
tests/absolutize_without_cwd.rs Adds unix-only child-process tests ensuring absolute inputs don’t require cwd availability.
tests/absolutize_with.rs Updates explicit-cwd tests to new _with signature (borrowed/owned direct args) and Windows drive-relative rules.
tasks/track_allocations/README.md Updates allocation-task documentation and methodology notes.
src/utils.rs Replaces ambient cwd helper with fallible try_get_current_dir() and caches only when enabled.
src/sugar_path.rs Redefines the sealed borrowed API surface, docs, and semantics for normalize/absolutize/relative/slash conversion.
src/sugar_path_buf.rs Introduces sealed consuming SugarPathBuf trait for allocation-reusing PathBuf operations.
src/lib.rs Updates crate-level docs, re-exports, and examples to reflect the redesigned API and consuming surface.
README.md Updates public README to explain the new API, borrowing/ownership rules, encoding policy, and examples.
CHANGELOG.md Documents breaking API changes, new methods, behavior changes, and migration notes.
benchmarks/windows-gnu.md Updates Windows-GNU reproduction doc to clarify evidence status and final-API context.
benchmarks/README.md Updates benchmarking methodology, workload description, and snapshot regeneration instructions.
benchmarks/allocations/x86_64-unknown-linux-gnu-rolldown.snap Updates committed allocation snapshot for Linux (rolldown configuration) for the new API.
benchmarks/allocations/x86_64-unknown-linux-gnu-default.snap Updates committed allocation snapshot for Linux (default configuration) for the new API.
benchmarks/allocations/aarch64-apple-darwin-rolldown.snap Updates committed allocation snapshot for macOS ARM64 (rolldown configuration) for the new API.
benchmarks/allocations/aarch64-apple-darwin-default.snap Updates committed allocation snapshot for macOS ARM64 (default configuration) for the new API.
benches/to_slash.rs Updates slash benchmarks to new strict/fallible APIs and consuming PathBuf reuse rows.
benches/relative.rs Updates relative benchmarks to preserve stable IDs while adapting to Cow<Path> return and requested outputs.
benches/normalize.rs Updates normalize benchmarks to exercise consuming into_normalized paths for owned receiver rows.
benches/absolutize.rs Updates benchmarks for explicit-cwd APIs without requiring caller-constructed Cow.
AGENTS.md Updates contributor guidance, commands, architecture notes, and PCR guidance.
.agents/docs/technology-stack.md Adds PCR doc describing toolchain pins and performance dependencies/evidence.
.agents/docs/README.md Adds PCR map routing contributors to relevant durable context docs.
.agents/docs/gotchas.md Adds PCR gotchas covering relative directionality, borrowing rules, cwd semantics, and encoding policy.
.agents/docs/goal.md Adds PCR doc describing project goals, success criteria, and non-goals.
.agents/docs/conventions.md Adds PCR doc capturing testing conventions, allocation/encoding coverage expectations, and platform gating.
.agents/docs/architecture.md Adds PCR doc describing the two-trait architecture, execution paths, and platform behavior boundaries.
.agents/docs/api-redesign.md Adds PCR doc capturing the rationale/decision record for the breaking API redesign and its evidence.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread AGENTS.md
Comment on lines 40 to 44
- **`src/sugar_path.rs`** — Trait definition with doc examples
- **`src/impl_sugar_path.rs`** — All implementations. Two impl blocks: one for `Path`, one for `T: Deref<Target = str>`. Contains `normalize_inner()`, `needs_normalization()`, `relative_str()` and helper functions
- **`src/sugar_path_buf.rs`** — Consuming `PathBuf` trait definition with doc examples
- **`src/impl_sugar_path.rs`** — All implementations. Two impl blocks: one for `Path`, one for `str`; `String` and other string-like values use normal deref method lookup. Contains `normalize_inner()`, `needs_normalization()`, `relative_str()` and helper functions
- **`src/utils.rs`** — `get_current_dir()` helper for `absolutize()`

Comment on lines +23 to +26
cargo allocs --write benchmarks/allocations/aarch64-apple-darwin-default.snap
cargo allocs-rolldown --write benchmarks/allocations/aarch64-apple-darwin-rolldown.snap
cargo allocs --check benchmarks/allocations/aarch64-apple-darwin-default.snap
cargo allocs-rolldown --check benchmarks/allocations/aarch64-apple-darwin-rolldown.snap
hyfdev added a commit that referenced this pull request Jul 12, 2026
Align architecture notes with try_get_current_dir after the ambient
cwd API returned Result.
hyfdev added a commit that referenced this pull request Jul 12, 2026
* docs: redesign public API guidance

* docs: complete public API guidance pass

Fill remaining method examples and try/lossy contracts, polish the
README for crates.io/docs.rs readers, and declare package docs metadata.

* ci: stop double-running Test on PR branch pushes

Restrict push triggers to main (match CodSpeed), cancel in-progress runs
for the same PR, and run host-independent fmt/doc once on Ubuntu.

* ci: keep only Linux and Windows Rolldown allocation gates

Drop macOS and default-feature committed snapshots. Continuous CI checks
the two primary-consumer Rolldown snaps only, and docs/PCR stay in sync.

* refactor: make cargo allocs the only allocation entry point

Always measure cached_current_dir in the tracker, drop allocs-rolldown,
and rename the committed snaps to plain target triples.

* docs: fix AGENTS.md cwd helper name after PR #40 review

Align architecture notes with try_get_current_dir after the ambient
cwd API returned Result.

* fix: silence clippy write_literal in allocation snapshot header

Inline the fixed cached_current_dir configuration label into the format
string so CI clippy -D warnings passes again.
graphite-app Bot pushed a commit to rolldown/rolldown that referenced this pull request Jul 12, 2026
## 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
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