Skip to content

Tracking issue for raw stabilization (raw::TraitObject) #27751

Closed

Description

@aturon

The std::raw module exports some representation details for the purposes of transmuting and taking things apart. Stabilizing these means pinning down the representation details forever.

One possibility is to instead provide various conversions, rather than asking people to use transmute, when we're sure the conversions will always be possible. Methods like from_raw_parts are already doing this.

The TraitObject case in particular is unsettled due to the potential for upcasting in the future.

cc @carllerche

CURRENT STATUS AS OF 2016-08-18: Discussed in @rust-lang/lang meeting. The situation is this. We expect that this will be insufficient in the future, particularly if/when we support trait objects like Trait1+Trait2 (which would require 2 vtables). We could stabilize it, since it would remain correct for all existing objects, but it'd be a shame. In contrast, the various "custom DST" proposals would allow for a much more flexible way of extracting and creating this data (sort of like from_raw_parts), so we think we'd prefer to explore that route. (from #27751 (comment))

Activity

  1. added
    T-langRelevant to the language team
    T-libs-api[DEPRECATED; DO NOT USE]
    B-unstableBlocker: Implemented in the nightly compiler and unstable.
    on Aug 12, 2015
  2. SimonSapin commented on Aug 13, 2015

    @SimonSapin
    Contributor

    raw::Slice can be replaced with [T]::len, [T]::as{,_mut}_ptr, and slice::from_raw_parts{,_mut}. Kill it.

    TraitObject is used in Servo:

    • To implement downcasting from trait objects of a custom trait, like std::error::Error does. It’s unfortunate that std::any::Any can not be re-used. (I understood why at some point, but forgot.)
    • Using obj.data as usize as an identifier. (LayoutId, OpaqueFlow)
    • To do some kind of inheritance. Getting a reference from a &Flow trait object to the BaseFlow (concrete struct) that is must be the first field of every implementors of the Flow trait. Yes, relying on struct field order.
    • To emulate Arc<Trait> before Arc supported DSTs. I’m trying to switch to Arc now.
  3. carllerche commented on Aug 13, 2015

    @carllerche
    Contributor

    I have used TraitObject a number of times.

    One case, in the bytes crate, I use TraitObject to avoid an allocation, which can add up to a significant performance win in some cases (for example, when using Rope).

    The insight is that, pretty often, implementations of ByteStr can fit in a pointer size. So, Bytes, which is a wrapper around a ByteStr trait object does an optimization where the data component of the trait object gets "inlined".

    Another case I had was building a somewhat involved tree structure, there would be many pointers to the same trait object. The goal was to get an entire node of the tree to fit in a cache line and duplicating the vtable ptr prevented this. So, in this case, I saved the vtable pointer only once and "reconstructed" the trait object on demand.

  4. added a commit that references this issue on Aug 18, 2015
  5. kamalmarhubi commented on Mar 5, 2016

    @kamalmarhubi
    Contributor

    I have a possible use case for stabilizing Slice: I would like to use byte slices directly as struct iovec for readv and writev in nix. There's an issue with more detail: nix-rust/nix#263

    Mostly I'm looking to exploit the (pointer, length) representation matching up with iovec, and thereby allowing a nice ergonomics win for calls using iovecs.

  6. alexcrichton commented on Mar 11, 2016

    @alexcrichton
    Member

    🔔 This issue is now entering its cycle-long final comment period 🔔

    Specifically, the libs team is considering deprecating raw::Slice and raw::Repr as these are replaced by std::slice functions.

    @kamalmarhubi we specifically don't want to stabilize the layout of slices to be used in places like that, hence the deprecation!

  7. added
    final-comment-periodIn the final comment period and will be merged soon unless new substantive objections are raised.
    and removed on Mar 11, 2016
  8. SimonSapin commented on Mar 11, 2016

    @SimonSapin
    Contributor

    Was TraitObject discussed?

  9. alexcrichton commented on Mar 11, 2016

    @alexcrichton
    Member

    Yes, and we neither want to stabilize it nor deprecate it yet, this module will stick around for that reason.

  10. aturon commented on Mar 11, 2016

    @aturon
    ContributorAuthor

    A bit more detail from the discussion at the meeting: TraitObject is, amongst the types that have ever appeared in this module, the most likely to change in the future. That's in part due to considerations about upcasting, multiple trait inheritance, and so on. It's unclear whether we will ever want to commit firmly to a representation here.

    That said, it'd be good to use this issue to track usecases for the raw representation, and see whether we can find other ways of accommodating them.

  11. kamalmarhubi commented on Mar 11, 2016

    @kamalmarhubi
    Contributor

    @alexcrichton

    @kamalmarhubi we specifically don't want to stabilize the layout of slices to be used in places like that, hence the deprecation!

    I figured as much. Maybe specialization and conditional compilation will let me be bad in the way I want to be there... :-)

    Thanks for the ping!

  12. 33 remaining items

  13. durka commented on Oct 13, 2017

    @durka
    Contributor
  14. SimonSapin commented on Oct 13, 2017

    @SimonSapin
    Contributor

    Even if the repr changes it has to include at least a data pointer, doesn’t it?

  15. durka commented on Oct 13, 2017

    @durka
    Contributor

    The reference says it is a "pointer-to-pointer cast" but doesn't say what that means. Sounds OK though?

  16. eddyb commented on Oct 13, 2017

    @eddyb
    Contributor

    @durka The casts are properly defined and there's even fat-to-fat casts which check the metadata and whatnot - they might be described in an RFC, or not at all, but that's orthogonal.

  17. SimonSapin commented on Oct 13, 2017

    @SimonSapin
    Contributor

    https://doc.rust-lang.org/nightly/nomicon/casts.html says:

    *T as *U where T, U: Sized
    *T as *U TODO: explain unsized situation

    and

    Note that lengths are not adjusted when casting raw slices - *const [u16] as *const [u8] creates a slice that only includes half of the original memory.

    Maybe it’s time to fix that TODO and define this more precisely?

  18. SimonSapin commented on Oct 28, 2018

    @SimonSapin
    Contributor

    rust-lang/rfcs#2580 proposes deprecating this.

  19. added
    I-libs-radarLibs issues that are tracked on the team's radar.
    on Jul 29, 2020
  20. SimonSapin commented on Apr 15, 2021

    @SimonSapin
    Contributor

    Deprecation PR: #84207

  21. SimonSapin commented on Apr 15, 2021

    @SimonSapin
    Contributor

    As an unstable feature, this can be removed a couple release cycles after the deprecation warning has been in place.

  22. crlf0710 commented on Jul 3, 2021

    @crlf0710
    Member

    Opened a removal pr at #86833.

  23. added a commit that references this issue on Jul 4, 2021
    71a567f
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

    A-trait-systemArea: Trait systemB-unstableBlocker: Implemented in the nightly compiler and unstable.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCI-libs-radarLibs issues that are tracked on the team's radar.T-langRelevant to the language teamT-libs-api[DEPRECATED; DO NOT USE]

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions