Skip to content

Conversation

@overlookmotel
Copy link
Member

@overlookmotel overlookmotel commented Aug 13, 2025

It's unsound for Vec to be Send because if you can move a Vec to another thread, you can call push on it and it may allocate in the arena. This is unsound because another thread may be simultaneously be doing the same with another Vec, and Bump is not thread-safe.

Remove the Send impl on Vec.

However, we do want Vec to be Sync. There's no reason why you shouldn't have 2 &Vec references on different threads, as &Vec doesn't allow mutating the Vec in any way. The only hole we had previously which made this unsound was the Vec::bump method, which was removed in #13039.

Just tighten up the trait bounds so that Vec<T> is Sync only if T is. This mirrors the standard library in relation to T. We're being more liberal than standard library in not requiring the allocator to be Sync too (Bump isn't), but that's OK because we don't have an equivalent of std::vec::Vec's allocator method (that was Vec::bump, and we've removed it).

The reason these 2 impls were added originally was as a quick fix to make oxc_semantic::Scoping Send and Sync. That is addressed in a later PR in this stack.

Copy link
Member Author

overlookmotel commented Aug 13, 2025


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • 0-merge - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@codspeed-hq
Copy link

codspeed-hq bot commented Aug 13, 2025

CodSpeed Instrumentation Performance Report

Merging #13041 will not alter performance

Comparing 08-12-fix_allocator_remove_unsound_send_impl_and_tighten_sync_requirements_for_vec_ (0815a89) with 08-12-fix_allocator_remove_vec_bump_method (af3b98e)

Summary

✅ 34 untouched benchmarks

@overlookmotel overlookmotel marked this pull request as ready for review August 13, 2025 00:33
@Dunqing
Copy link
Member

Dunqing commented Aug 13, 2025

Have you tried this stack in Rolldown? This is the only concern we adjust Send and Sync. Oh, I saw you mentioned that in #13042 (comment)

@graphite-app graphite-app bot force-pushed the 08-12-fix_allocator_remove_clone_impl_from_vec_ branch from 82da014 to 32f9901 Compare August 13, 2025 11:52
@graphite-app graphite-app bot requested review from Sysix and camc314 as code owners August 13, 2025 11:52
@graphite-app graphite-app bot force-pushed the 08-12-fix_allocator_remove_unsound_send_impl_and_tighten_sync_requirements_for_vec_ branch from 1529968 to 49299c7 Compare August 13, 2025 11:53
@overlookmotel overlookmotel changed the base branch from 08-12-fix_allocator_remove_clone_impl_from_vec_ to graphite-base/13041 August 18, 2025 23:53
@overlookmotel overlookmotel changed the base branch from graphite-base/13041 to 08-12-fix_allocator_remove_clone_impl_from_vec_ August 18, 2025 23:54
@overlookmotel overlookmotel changed the base branch from 08-12-fix_allocator_remove_clone_impl_from_vec_ to graphite-base/13041 August 18, 2025 23:54
@overlookmotel overlookmotel force-pushed the 08-12-fix_allocator_remove_unsound_send_impl_and_tighten_sync_requirements_for_vec_ branch from 49299c7 to bb6abbc Compare August 18, 2025 23:55
@overlookmotel overlookmotel changed the base branch from graphite-base/13041 to 08-12-fix_allocator_remove_vec_bump_method August 18, 2025 23:55
@graphite-app graphite-app bot added the 0-merge Merge with Graphite Merge Queue label Aug 19, 2025
@graphite-app
Copy link
Contributor

graphite-app bot commented Aug 19, 2025

Merge activity

…ments for `Vec` (#13041)

It's unsound for `Vec` to be `Send` because if you can move a `Vec` to another thread, you can call `push` on it and it may allocate in the arena. This is unsound because another thread may be simultaneously be doing the same with another `Vec`, and `Bump` is not thread-safe.

Remove the `Send` impl on `Vec`.

However, we do want `Vec` to be `Sync`. There's no reason why you shouldn't have 2 `&Vec` references on different threads, as `&Vec` doesn't allow mutating the `Vec` in any way. The only hole we had previously which made this unsound was the `Vec::bump` method, which was removed in #13039.

Just tighten up the trait bounds so that `Vec<T>` is `Sync` only if `T` is. This mirrors the standard library in relation to `T`. We're being more liberal than standard library in not requiring the allocator to be `Sync` too (`Bump` isn't), but that's OK because we don't have an equivalent of `std::vec::Vec`'s [`allocator` method](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.allocator) (that was `Vec::bump`, and we've removed it).

The reason these 2 impls were added originally was as a quick fix to make `oxc_semantic::Scoping` `Send` and `Sync`. That is addressed in a later PR in this stack.
@graphite-app graphite-app bot force-pushed the 08-12-fix_allocator_remove_vec_bump_method branch from 4a35895 to af3b98e Compare August 19, 2025 21:36
@graphite-app graphite-app bot force-pushed the 08-12-fix_allocator_remove_unsound_send_impl_and_tighten_sync_requirements_for_vec_ branch from bb6abbc to 0815a89 Compare August 19, 2025 21:37
graphite-app bot pushed a commit that referenced this pull request Aug 19, 2025
…ment for `HashMap` (#13203)

Same as #13041.

It's unsound for `oxc_allocator::HashMap` to be `Send` because if you can move a `HashMap` to another thread, you can call `insert` on it and it may allocate in the arena. This is unsound because another thread may be simultaneously be doing the same with another `HashMap`, and `Bump` is not thread-safe.

Remove the `Send` impl on `HashMap`.

However, we do want `HashMap` to be `Sync`. There's no reason why you shouldn't have 2 `&HashMap` references on different threads, as `&HashMap` doesn't allow mutating the `HashMap` in any way.

Tighten up the trait bounds so `HashMap<K, V>` is `Sync` only if `K` and `V` both are.

This is not yet completely sound. There are a couple of holes I'm aware of:

1. `allocator` method which allows obtaining a `&Bump` from a `&HashMap`.
2. `clone` which allocates into arena, taking only an immutable `&self` reference.

This PR closes those holes as much as possible without a major refactor. It's not *completely* sound, but it's at least now quite difficult to commit UB - it'd be unlikely to happen by accident.

So, not perfect, but at least there's now only a crack in the window, rather than the front door swinging wide open.

---

The reason these 2 impls were added originally was as a quick fix to make `oxc_semantic::Scoping` `Send` and `Sync`. That is addressed in the next PR in this stack.
graphite-app bot pushed a commit that referenced this pull request Aug 19, 2025
…3042)

Previous PRs removed unsound `Sync` impl for `Allocator` (#13033) and `Send` impl for `Vec` (#13041).

Previously `ScopingCell` was `Send` and `Sync` (and therefore `Scoping` was too). The recent PRs mean that `ScopingCell` lost those traits too.

This PR implements both traits again for `ScopingCell` by restricting its API slightly, so now it is `Send` and `Sync` again, but this time in a manner which maintains soundness.

The comments in the code outline the logic of why I believe it to be sound.

Rolldown relies on `ScopingCell` being `Send` and `Sync`. After this PR, this stack does not require any changes in Rolldown. I've checked that `cargo ck` in Rolldown passes when using the version of Oxc from this branch.
@graphite-app graphite-app bot removed the 0-merge Merge with Graphite Merge Queue label Aug 19, 2025
Base automatically changed from 08-12-fix_allocator_remove_vec_bump_method to main August 19, 2025 21:44
@graphite-app graphite-app bot merged commit 0815a89 into main Aug 19, 2025
27 checks passed
@graphite-app graphite-app bot deleted the 08-12-fix_allocator_remove_unsound_send_impl_and_tighten_sync_requirements_for_vec_ branch August 19, 2025 21:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-bug Category - Bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants