Skip to content

Conversation

@overlookmotel
Copy link
Member

@overlookmotel overlookmotel commented Aug 13, 2025

Vec::bump method is unsound.

  • Vec is Sync, which means that you can have 2 &Vec references on different threads.
  • Vec::bump allows converting a &Vec into a &Bump, which means you can obtain 2 &Bumps on different threads.
  • Bump uses interior mutability, so you only need a &Bump (not &mut Bump) to allocate into that arena.
  • Bump is not thread-safe (hence it's not Sync) and allocating into the arena from 2 different threads simultaneously is UB.

We don't use this method anyway, and I can't see any prospect of us doing so in future, so remove it. This will enable us to keep Vec being Sync without unsoundness.

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 #13039 will not alter performance

Comparing 08-12-fix_allocator_remove_vec_bump_method (af3b98e) with 08-12-fix_allocator_remove_clone_impl_from_vec_ (9ac418d)1

Summary

✅ 34 untouched benchmarks

Footnotes

  1. No successful run was found on 08-12-fix_allocator_remove_clone_impl_from_vec_ (9ac418d) during the generation of this report, so 98eac10 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@graphite-app graphite-app bot force-pushed the 08-12-fix_allocator_remove_unsound_impl_sync_for_allocator_ branch from 6b33f35 to 68b7ce3 Compare August 13, 2025 11:51
@graphite-app graphite-app bot requested review from Sysix and camc314 as code owners August 13, 2025 11:51
@graphite-app graphite-app bot force-pushed the 08-12-fix_allocator_remove_unsound_impl_sync_for_allocator_ branch from 68b7ce3 to b76e7e6 Compare August 13, 2025 11:52
@graphite-app graphite-app bot force-pushed the 08-12-fix_allocator_remove_vec_bump_method branch from dda09b3 to 7eed95f Compare August 13, 2025 11:52
@overlookmotel overlookmotel changed the base branch from 08-12-fix_allocator_remove_unsound_impl_sync_for_allocator_ to graphite-base/13039 August 18, 2025 23:53
@overlookmotel overlookmotel changed the base branch from graphite-base/13039 to 08-12-fix_allocator_remove_unsound_impl_sync_for_allocator_ August 18, 2025 23:54
@overlookmotel overlookmotel changed the base branch from 08-12-fix_allocator_remove_unsound_impl_sync_for_allocator_ to graphite-base/13039 August 18, 2025 23:54
@overlookmotel overlookmotel force-pushed the 08-12-fix_allocator_remove_vec_bump_method branch from 7eed95f to 4a35895 Compare August 18, 2025 23:54
@overlookmotel overlookmotel changed the base branch from graphite-base/13039 to 08-12-fix_allocator_remove_clone_impl_from_vec_ August 18, 2025 23:54
@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

`Vec::bump` method is unsound.

* `Vec` is `Sync`, which means that you can have 2 `&Vec` references on different threads.
* `Vec::bump` allows converting a `&Vec` into a `&Bump`, which means you can obtain 2 `&Bump`s on different threads.
* `Bump` uses interior mutability, so you only need a `&Bump` (not `&mut Bump`) to allocate into that arena.
* `Bump` is not thread-safe (hence it's not `Sync`) and allocating into the arena from 2 different threads simultaneously is UB.

We don't use this method anyway, and I can't see any prospect of us doing so in future, so remove it. This will enable us to keep `Vec` being `Sync` without unsoundness.
graphite-app bot pushed a commit that referenced this pull request Aug 19, 2025
`Vec::clone` method is unsound, for the same reasons as `Vec::bump` is (#13039).

`clone` only takes a `&self` and then uses it to access the `&Bump` contained in `Vec`, and allocates into that arena. Because `Vec` is `Sync`, that can result in 2 threads allocating into same `Bump` simultaneously, which is UB.

`Clone` is of limited use, because usually usually the contents of the `Vec` aren't `Clone`. We have `CloneIn` trait for this purpose.

We don't currently use `Clone` anywhere, so we can remove it.
@graphite-app graphite-app bot force-pushed the 08-12-fix_allocator_remove_clone_impl_from_vec_ branch from 72247e6 to 9ac418d Compare August 19, 2025 21:36
@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 bot pushed a commit that referenced this pull request Aug 19, 2025
…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 removed the 0-merge Merge with Graphite Merge Queue label Aug 19, 2025
Base automatically changed from 08-12-fix_allocator_remove_clone_impl_from_vec_ to main August 19, 2025 21:42
@graphite-app graphite-app bot merged commit af3b98e into main Aug 19, 2025
27 checks passed
@graphite-app graphite-app bot deleted the 08-12-fix_allocator_remove_vec_bump_method branch August 19, 2025 21:44
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