New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracking issue for DST coercions (coerce_unsized, unsize) stabilization #27732

Open
aturon opened this Issue Aug 12, 2015 · 26 comments

Comments

Projects
None yet
@aturon
Member

aturon commented Aug 12, 2015

DST coercions were the last part of DST to land, and are still undergoing some changes.

Before stabilization, at the very least the API surface here needs some scrutiny from the libs team for naming and other conventions issues.

cc @nrc @Gankro

@aturon

This comment has been minimized.

Member

aturon commented Sep 23, 2015

@nrc, what's your sense of the status for these features? Do you feel ready to stabilize after the libs team takes a look?

@nrc

This comment has been minimized.

Member

nrc commented Sep 23, 2015

My feeling (and it is really just a feeling, I have no data to back this up) is that DST coercions haven't yet got the use they need to prove themselves for stabilisation. I'd love to be wrong about this - if someone could show me a bunch of code doing stuff with DST coercions I'd be very happy. OTOH, I don't think there is anything fundamentally wrong with them, so it would not be a waste of time for the libs team to take a look.

@photino

This comment has been minimized.

photino commented Sep 24, 2015

Why is the marker named Unsize? Unsized sounds better, since we already have Sized.

@arielb1

This comment has been minimized.

Contributor

arielb1 commented Sep 24, 2015

@photino

It goes the wrong way around - for example, we have [i8; 2]: Unsize<[u8]> (and also [i8; 2]: Unsize<fmt::Debug>). We can swap the order of parameters - U: Unsized<T> if U is thean unsized version of T.

@rphmeier

This comment has been minimized.

Contributor

rphmeier commented Dec 18, 2015

Can we move to stabilize this? It's been unchanged for 5 months and I've heard no complaints about it.

@Gankro

This comment has been minimized.

Contributor

Gankro commented Dec 18, 2015

I don't recall having any issues with this in libstd. The correct way to use this is basically a witchcraft incantation (mostly because these are under-the-covers things one never interacts with in real code), but as far as I know, there's know way to use it dangerously wrong? The whole thing Just Works.

I guess one thing I've never really thought about is why one needs to talk about whether the pointed-to value is unsizeable or whatever. Why can't one simply declare that pointer X is an unsizable one, and have all that junk automatic? Is this desirable to have for generic consumers...?

@jnicholls

This comment has been minimized.

jnicholls commented Jan 24, 2016

It's desirable for generic consumers of e.g. Arena allocators that allocate a Sized type that implements a trait unknown to the allocator, and the consumer wants to coerce the allocated result to an allocated trait object.

See https://gitlab.com/Bastacyclop/rust_arena/blob/master/src/lib.rs in the tests. It's a decent use case. How would you recommend doing this otherwise?

@stevenblenkinsop

This comment has been minimized.

stevenblenkinsop commented Jan 29, 2016

Is the lack of support for enums deliberate, temporary, or merely overlooked?

@aturon

This comment has been minimized.

Member

aturon commented Feb 1, 2016

I'm nominating this for discussion at the next lang team meeting.

@aturon aturon added the I-nominated label Feb 1, 2016

@Gankro

This comment has been minimized.

Contributor

Gankro commented Feb 2, 2016

@jnicholls maybe I'm missing something, but just mark the one pointer field that will be Unsized as coercable: https://gitlab.com/Bastacyclop/rust_arena/blob/master/src/lib.rs#L41

It seems to me that all the impl<...> CoerceUnsized for ... is trivially derivable from the claim that that field should be coercable.

@jnicholls

This comment has been minimized.

jnicholls commented Feb 2, 2016

@Gankro Sorry I don't follow what you mean. Can you provide an example?

@Gankro

This comment has been minimized.

Contributor

Gankro commented Feb 2, 2016

Oops, something clobbered my selection, I meant to link to: https://gitlab.com/Bastacyclop/rust_arena/blob/master/src/lib.rs#L59

Basically instead of

pub struct Allocated<'a, 'b, T: 'b + ?Sized> {
    reference: &'b mut T,
    phantom: PhantomData<&'a ()>
}

impl<'a, 'b, T: ?Sized, U: ?Sized> CoerceUnsized<Allocated<'a, 'b, U>> for Allocated<'a, 'b, T>
    where U: 'b, T: 'b + Unsize<U> {}

You would just do something like:

#[coerce_unsized(T)]
pub struct Allocated<'a, 'b, T: 'b + ?Sized> {
    reference: &'b mut T,
    phantom: PhantomData<&'a ()>
}

@aturon aturon removed the T-libs label Feb 18, 2016

@aturon

This comment has been minimized.

Member

aturon commented Feb 18, 2016

cc @eddyb

@aturon

This comment has been minimized.

Member

aturon commented Feb 18, 2016

Removed T-libs tag, but note that we'd like to review the naming conventions here before stabilization.

@eddyb

This comment has been minimized.

Member

eddyb commented Feb 18, 2016

There's room for generalization and a good chance we might want Source: Coerce<Target>.
See this comment in response to wanting &mut T reborrows working through structs.

@apasel422

This comment has been minimized.

Member

apasel422 commented Feb 22, 2016

Right now, because T does not implement Unsize<T>, one cannot use CoerceUnsized to support optional coercions in a generic context. (My use case is supporting DSTs with the placement API). Since &T can trivially be coerced to &T, would it make sense to add the identity impl?

@tomaka

This comment has been minimized.

Contributor

tomaka commented Feb 23, 2016

I'm not very familiar with how this works, but shouldn't the T of CoerceUnsized be T: ?Sized?
Right now T is required to be Sized, which doesn't make sense for me. Example.

@arielb1

This comment has been minimized.

Contributor

arielb1 commented Feb 23, 2016

@tomaka

You implement CoerceUnsized on pointer types, not on DST types.

e.g.

impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}

@aturon aturon removed the I-nominated label Feb 26, 2016

@alexcrichton alexcrichton added T-libs and removed T-libs labels Mar 7, 2016

@alexcrichton

This comment has been minimized.

Member

alexcrichton commented Mar 8, 2016

(adding T-libs as this has a library API associated with it which needs stabilization)

@nikomatsakis

This comment has been minimized.

Contributor

nikomatsakis commented Mar 11, 2016

So at a recent @rust-lang/lang meeting we discussed this. I think everyone felt...somewhat comfortable with the idea of going forward, but we also wanted to do a thorough review of the current status of the code, along with a comparison against the existing specifications, to make sure everything is well aligned.

@eddyb

This comment has been minimized.

Member

eddyb commented Mar 11, 2016

@nikomatsakis The problem, though, is that the RFC is intentionally provisional, mostly to get Rc and Arc working with DSTs. I would like to see an attempt at generalization before stabilizing it (I believe the compiler code would "just work" with more than one field being coerced, and various coercion modes, not just Unsize, with minimal changes).

Maybe with specialization we can even encode Deref coercions in a general Coerce trait.

@arielb1

This comment has been minimized.

Contributor

arielb1 commented Mar 11, 2016

@eddyb

Deref coercions involve transitivity, which the trait system does not try to support.

@abonander

This comment has been minimized.

Contributor

abonander commented Feb 4, 2017

@nrc triage ping

@nrc

This comment has been minimized.

Member

nrc commented Feb 7, 2017

No change. I think we are waiting for some kind of custom DST RFC before moving forward with stabilisation here.

@H2CO3

This comment has been minimized.

H2CO3 commented Jun 5, 2017

@nrc @Gankro Any progress with this? It's really annoying that my beloved custom smart pointers can't point to trait objects in the lack of stable Unsize and CoerceUnsized.

@omni-viral

This comment has been minimized.

Contributor

omni-viral commented Feb 8, 2018

What if instead of using Unsize and CoerceUnsized directly in libraries we could implement From for all pointers from std which implement CoerceUnsized.
For example.

impl<T, U> From<Box<T>> for Box<U>
where
  T: Unsize<U>
{
  fn from(value: Box<T>) -> Box<U> {
    value as Box<U>
  }
}

In this case we could implement From for our pointer wrappers relying on From implementation of pointers.
And there will be no issues with converting multiple fields of the struct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment