Skip to content

Tracking Issue for SyncView #98407

Closed

Description

@guswynn

View all comments

Feature gate: #![feature(exclusive_wrapper)]

This is a tracking issue for the SyncView wrapper struct.

This structure can be used to upgrade non-Sync objects into Sync ones, by only offering mutable access to the underlying object. This can be useful with Send-but-not-Sync futures (like BoxFutures)

Public API

// core::sync
#[derive(Default)]
struct SyncView<T: ?Sized> { ... }

unsafe impl<T: ?Sized> Sync for SyncView<T> {}
// via auto traits:
// unsafe impl<T: ?Sized + Send> Send for SyncView<T> {}

impl<T> SyncView<T> {
    pub const fn new(x: T) -> Self;
    pub const fn into_inner(self) -> T;
}

impl<T: ?Sized> SyncView<T> {
    pub const fn as_pin(self: Pin<&Self>) -> Pin<&T>;
    pub const fn as_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T>;
    pub const fn from_mut(x: &mut T) -> &mut Self;
    pub const fn from_pin_mut(x: Pin<&mut T>) -> Pin<&mut Self>;
}

impl<T> From<T> for SyncView<T> { ... }

impl<T: ?Sized + Sync> AsRef<T> for SyncView<T> { ... }
impl<T: ?Sized> AsMut<T> for SyncView<T> { ... }

// Unconditionally implemented regardless of `T: Sync`:
impl<T: ?Sized> Debug for SyncView<T> { ... }

// + a bunch of forwarding impls (Clone, Copy, PartialEq, FnOnce,
// Future etc.) that require `Sync` when impl uses `&self`, and
// not when impl uses `&mut self`.
//
// Not yet `Iterator`, that has both `&self` and `&mut self` methods.

Steps / History

Unresolved Questions

  • Figure out naming.
  • Bikeshed certain method names (as_pin versus as_pin_ref comes to mind).
  • Address the issue with the documentation example that was pointed out in Example for std::sync::SyncView is dubious #146245.
  • Decide on the fate of the impl Debug (currently, the only nontrivial API surface that &SyncView<impl ?Sync> unconditionally implements).

Activity

  1. added
    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
    T-libs-api[DEPRECATED; DO NOT USE]
    on Jun 22, 2022
  2. clarfonthey commented on Jun 24, 2022

    @clarfonthey
    Contributor

    This is probably a bikeshed, but perhaps the get_pin_mut method could be directly implemented on Pin<Exclusive<T>>, so that it can share the same name as the regular Exclusive<T> version? Then maybe both could be named get_mut, or even get since you'll have to use it to access non-mutable methods, just with exclusive access.

    This does make it asymmetric with from_pin_mut, though, unless there were a Pin::exclusive method.

  3. guswynn commented on Jun 29, 2022

    @guswynn
    ContributorAuthor
  4. Nemo157 commented on Oct 20, 2022

    @Nemo157
    Contributor

    To provide some motivation I have been using a more limited internal version of this for about 3 years in async-compression. This is the sole bit of unsafety in that crate so I would love to be able to offload that onto std.

  5. guswynn commented on Oct 29, 2022

    @guswynn
    ContributorAuthor

    @Nemo157 I think we should try to get this in at 1.66, next week ill take a look at writing a stabilization report

  6. zachs18 commented on Nov 13, 2022

    @zachs18
    Contributor

    For the same reason that Exclusive can unconditionally implement Sync, I believe it can also unconditionally implement core::panic::RefUnwindSafe (which claims that a shared reference to the type is unwind-safe (i.e. can cross a panic boundary without introducing logic errors), which &Exclusive is, because it has no API).

    I don't know if it would be that useful (even ignoring that there's been some disucssion about deprecating (Ref)UnwindSafe), but I believe it could be added after stabilization if it is wanted, so it's not urgent or blocking.

  7. harudagondi commented on Feb 17, 2023

    @harudagondi
    Contributor

    Interestingly, in bevyengine/bevy#7718, they are adding a method called read that allows shared access to their Exclusive analogue as long as the inner type implements Sync.

  8. alice-i-cecile commented on Feb 17, 2023

    @alice-i-cecile

    Q: What's the use case for a SyncCell when the type is already Sync?
    A: Generics, mostly. When designing an API you might not know if a type parameter is Sync or not, so you'd put it in a SyncCell. Then when you use that API with a concrete type, you can bypass the exclusivity if that type is Sync

    The method above is quite useful for us, but is a contradiction with the Exclusive name of this type. As a result, we'd like to suggest renaming the type to something compatible, and adding the method linked in the PR above.

    This is quite a useful type, and it would be a shame to see something limited get locked in via stabilization.

    (summarized from conversation in the Bevy Discord).

  9. zachs18 commented on Feb 18, 2023

    @zachs18
    Contributor

    I agree that SyncCell or something like it could be a better name than Exclusive in the presence of a fn read(&self) -> &T where T: Sync-like method, but I don't necessarily think that Exclusive being a contradictory name/having an exception for Exclusive<T: Sync> would be too bad. There's somewhat of precedent with Pin<Pointer>, which has an "exception" when Pointer::Target: Unpin, and indeed has additional API in that case, e.g. Pin::get_mut.

  10. joseph-gio commented on Feb 19, 2023

    @joseph-gio
    Contributor

    I don't think Pin is a the best comparison here. It makes total sense that the Unpin trait would negate Pin, for obvious reasons. However, it does not make sense that Sync would negate Exclusive, since those concepts are orthogonal. If shared access is going to be supported for this type, I don't think it makes sense to keep the current name.

  11. clarfonthey commented on Feb 19, 2023

    @clarfonthey
    Contributor

    The main issue with using the Cell terminology I can see is that Exclusive doesn't use UnsafeCell internally, whereas all other forms of Cell do. In some sense, this actually makes it a sort of anti-cell; cells let you perform writes with immutable references, whereas Exclusive prevents you from performing reads with immutable references.

    What we have is some sort of static mutex, but I'm not sure if using that terminology is helpful either.

  12. joseph-gio commented on Feb 20, 2023

    @joseph-gio
    Contributor

    I agree that the Cell terminology isn't great, since this type doesn't use interior mutability.

    I think the name should emphasize the fact that the purpose of this type is to gurantee Sync-ness. A name along the lines of SyncSafe<T> would be ideal IMO -- this describes the purpose of this type, and doesn't make shared access contradictory.

  13. nikita240 commented on Aug 9, 2023

    @nikita240

    We should just name it Iceberg since the type is used to Sync the Unsyncable.

  14. 102 remaining items

  15. tgross35 commented on Sep 19, 2026

    @tgross35
    Member

    I thought they both work, but it seems like that one didn't resolve it either? Wonder if it's related to FCP team membership updates.

  16. clarfonthey commented on Sep 19, 2026

    @clarfonthey
    Contributor

    Shouldn't be…

  17. clarfonthey commented on Sep 19, 2026

    @clarfonthey
    Contributor

    Okay, actually, the docs are wrong, and it worked earlier in this thread? I think rfcbot is just broken.

  18. ChrisDenton commented on Sep 19, 2026

    @ChrisDenton
  19. tgross35 commented on Sep 19, 2026

    @tgross35
    Member

    Guess those examples just aren't improved enough 🙃

    On a more serious note, I assume #146245 can be closed?

  20. tisonkun commented on Sep 26, 2026

    @tisonkun
    Contributor

    Here is a stabilization PR for review - #163366

  21. clarfonthey commented on Sep 26, 2026

    @clarfonthey
    Contributor

    I guess we're just gonna bypass rfcbot here as obviously broken, since it's been resolved? Are we okay with not waiting the full 10 days since this is a super old FCP?

    cc @Mark-Simulacrum in case you want to inspect the DB to see what's up

  22. clarfonthey commented on Sep 26, 2026

    @clarfonthey
    Contributor

    Okay, rechecking the date on Andrew's comment, it actually has been 10 days since the resolution. We didn't actually notify TWIR on this, but since we have an entire release cycle to undo this stabilisation, I'm going to just say it's fine and merge the other PR.

  23. added and removed
    proposed-final-comment-periodProposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off.
    on Sep 26, 2026
  24. added a commit that references this issue on Sep 26, 2026
  25. removed
    disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.
    on Sep 26, 2026
  26. added a commit that references this issue on Sep 26, 2026
  27. added
    disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.
    on Sep 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCT-libsRelevant to the library team, which will review and decide on the PR/issue.disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions