rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.35k stars 12.59k forks source link

Tracking issue for dyn upcasting coercion #65991

Open alexreg opened 4 years ago

alexreg commented 4 years ago

This is a tracking issue for RFC3324. Corresponding MCP is here. The feature gate for the issue is #![feature(trait_upcasting)].

STATUS UPDATE

We are in the process of stabilizing.

About tracking issues

Tracking issues are used to record the overall progress of implementation. They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions. A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature. Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.

Steps

Previous discussions

Unresolved Questions

Implementation history

scottmcm commented 1 year ago

This was discussed in triage, so I'll remove the concern @rfcbot resolve ensure-we-discuss-lcnr's-thoughts-in-triage

apiraino commented 1 year ago

Were all concerns raised by @WaffleLapkin in this comment ticked/discussed?

(apologies in advance if I missed something, I am slightly struggling to follow the technical details of the discussion)

tmandry commented 1 year ago

@apiraino I believe those should be addressed in some form in the stabilization report by the time it's published. I think T-types is now driving this to completion, but a number of other people have contributed to the draft (https://hackmd.io/QggP6SJVTa2jb7DjGq0vrQ?both).

nikomatsakis commented 1 year ago

Hi folks, we talked about this in our @rust-lang/types meeting. We all agreed that we'd like to see a better stabilization report that covers the trait system implementation and, ideally, modeling for trait upcasts in a-mir-formality.

I'm up to mentor someone on the latter if anybody has time to commit, please reach out.

EDIT: We decided a write-up suffices, see below.

nikomatsakis commented 12 months ago

We talked about this in our rust-lang/types meetup. While I still very much want to see this covered in a-mir-formality, we agreed that we shouldn't block on that. We would be happy to move forward with an improved stabilization report that covered more technical details, included links to the various writeups and decisions we've made. The major piece of missing docs is covering the interaction with trait selection -- @compiler-errors has recently reimplemented this and indicated a willingness to write it up (perhaps for rustc-dev-guide). I believe that the rest is already written and we can compile a stabilization report that links to the various places.

nikomatsakis commented 11 months ago

@rfcbot reviewed

nikomatsakis commented 11 months ago

@rfcbot concern types-team-sign-off

I am adding a concern that @rust-lang/types wants to be happy with the impl details (and especially @lcnr) -- @compiler-errors covered the details of type system interactions in rust-lang/rustc-dev-guide#1817 though.

lcnr commented 11 months ago

I am happy with the impl details. I had some other concerns in https://github.com/rust-lang/rust/issues/65991#issuecomment-1672782595.

While #101336 has still not been closed, everything seems now documented in https://hackmd.io/QggP6SJVTa2jb7DjGq0vrQ, so :+1: from my end.

nikomatsakis commented 11 months ago

@rfcbot resolve types-team-sign-off

see add'l discussion here

traviscross commented 11 months ago

@rustbot labels +I-lang-nominated

This was discussed in a recent T-types meeting. As @lcnr stated above, the concerns about the stabilization report and documentation have been resolved, so this is now unblocked. @nikomatsakis has proposed that we re-highlight this issue for T-lang, so let's renominate.

GregoryConrad commented 11 months ago

Not sure this has been mentioned yet, but seems related: #32220 should be possible now that Rust has upcasting support (at least in nightly)?

Edit: it looks like yes, see https://github.com/rust-lang/rfcs/issues/2035

nikomatsakis commented 11 months ago

We discussed @WaffleLapkin's list of unresolved concerns in the rust-lang triage meeting and had this text which I will add to the stabilization report:

tmandry commented 11 months ago

@rfcbot reviewed

rfcbot commented 11 months ago

:bell: This is now entering its final comment period, as per the review above. :bell:

NobodyXu commented 11 months ago

If the upcasting feature isn't used, can it be optimized out by compiler?

WaffleLapkin commented 11 months ago

@NobodyXu if a type is not ever coerced to a trait object, then the compiler won't generate a vtable. Otherwise, if a type is coerced, then the compiler will not be able to change the layout of the vtable based on it's usage.

NobodyXu commented 11 months ago

Thanks, it makes sense since it's hard to do that.

traviscross commented 10 months ago

@rustbot labels -I-lang-nominated

The proposal to do this is in FCP. Let's remove the nomination until and unless there is something more to do here.

Mergulsevdova commented 10 months ago

This is a tracking issue for RFC3324. Corresponding MCP is here.

The feature gate for the issue is #![feature(trait_upcasting)].

STATUS UPDATE

We are in the process of stabilizing.

About tracking issues

Tracking issues are used to record the overall progress of implementation.

They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions.

A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature.

Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.

Steps

Previous discussions

Unresolved Questions

  • Currently CoerceUnsized trait cannot express this case: a smart pointers that wrap a raw pointer and don't guarantee via a custom invariant that it is valid. Maybe a separate CoerceUnsizedUnsafe trait is needed. (see https://github.com/rust-lang/rust/pull/88010#issuecomment-898893209).

  • Should we make upcasting opt-in in some form to limit vtable size by default? The current inclination of the lang-team is "no", but it would be useful to gather data on how much supporting upcasting contributors to overall binary size.

  • Before stabilizing it we should check that libs-api is ok with upcasting for all dyn-allowed traits in the library, since those we can't change. (addressed by https://github.com/rust-lang/rust/issues/65991#issuecomment-1369970129)

  • Should we add an opt-out mechanism, and extend library stabilization checklist with "do we want to opt-out for now"?

Implementation history

-

rfcbot commented 10 months ago

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

This will be merged soon.

Ekleog commented 9 months ago

I just tried using this feature to upcast to Any + Send + Sync, and it seems to me like this is currently not allowed:

trait DynSized: 'static + Any + Send + Sync + DeepSizeOf {}
impl<T: 'static + Any + Send + Sync + DeepSizeOf> DynSized for T {}

fn main() {
    let ptr = Arc::new(()) as Arc<dyn DynSized>;
    let ptr_any = ptr as Arc<dyn Any + Send + Sync>;
    // my goal:
    let res = Arc::<dyn Any + Send + Sync>::downcast::<()>(ptr);
}

(playground link)

With references, the situation does not seem better than with Arc: this does not compile either

fn main() {
    let ptr = &() as &'static dyn DynSized;
    let ptr_any = ptr as &'static (dyn Any + Send + Sync);
}

(playground link)

Is this expected? I can't find any reference to this limitation, neither explicitly in the RFC text nor in this tracking issue. The RFC text does mention not supporting upcasting to multiple traits, but I'd have expected lifetimes as well as auto traits to not be included in the limitation.

If it is expected that this feature is stabilized without this support, does anyone know where I should watch, to know of the news on that front?

GregoryConrad commented 9 months ago

@Ekleog you can probably do a workaround like:

trait AnySendSync: Any + Send + Sync {}
impl<T: Any + Send + Sync> AnySendSync for T{}

Then upcast to AnySendSync instead of Any + Send + Sync. On my phone though so can’t verify if this actually works

Edit: you’ll also likely have to change your DynSized to be DynSized: AnySendSync + DeepSizeOf 👍

Ekleog commented 9 months ago

Unfortunately, it looks like [I still cannot downcast, because I need to upcast Arc<dyn AnySendSync> to Arc<dyn Any + Send + Sync> in order to be able to downcast, and this still does not compile :/

CAD97 commented 9 months ago

It's certainly not ideal due to requiring unsafe, but a downcast_ref to check followed by a Arc::from_raw(arc.as_raw().cast()) would at least be be a sound workaround.

yshui commented 9 months ago

@Ekleog how about this? this has an extra T: Sized restriction though, don't know if it can be better.

use std::any::Any;
use std::sync::Arc;

trait DeepSizeOf {} // from deepsize
impl DeepSizeOf for () {}

trait AnySendSync: Any + Send + Sync {
    fn explode(self: Arc<Self>) -> Arc<dyn Any + Send + Sync>;
}
impl<T: Any + Send + Sync> AnySendSync for T {
    fn explode(self: Arc<T>) -> Arc<dyn Any + Send + Sync> {
        self
    }
}
trait DynSized: 'static + AnySendSync + DeepSizeOf {}
impl<T: 'static + AnySendSync + DeepSizeOf> DynSized for T {}

fn main() {
    let ptr = Arc::new(()) as Arc<dyn DynSized>;
    let ptr_anysendsync = ptr as Arc<dyn AnySendSync>; // works fine
    let ptr_any = ptr_anysendsync.explode();
    let res = ptr_any.downcast::<()>();
}

i guess upcasting coercion exists to solve this kind of inefficiencies... but since upcasting to a group of traits isn't possible right now.

RalfJung commented 9 months ago

Closed issues are not a good place for discussion, please open a new issue or discuss on Zulip or the forums.

upcasting to a group of traits isn't possible right now

Indeed that's the core here, you can only upcast to a single trait. Could be interesting to discuss extending this to "one trait plus any number of marker traits" but that's an extension which needs a new issue. :)

Ekleog commented 9 months ago

Let's continue discussion on my upcasting issue on this separate issue opened by @compiler-errors :) Incidentally, it is currently being solved in this PR also by @compiler-errors (lots of thanks :heart:)

@dhardy As for the downcasting you're mentioning, I'm not sure what you're thinking of? But if/when you open a separate issue to discuss it, please tag me!

dhardy commented 9 months ago

@Ekleog regarding downcast, see https://internals.rust-lang.org/t/pre-rfc-make-downcast-user-friendly/20092

steffahn commented 8 months ago

I’ve come across some soundness issues with upcasting today. Readers of this thread might be interested ^^

PoignardAzur commented 5 months ago

Can we have a status update with regards to the reverted stabilization? The current status update says "We are in the process of stabilizing" since January, with no mention of the recent soundness issues.

WaffleLapkin commented 5 months ago

The stabilization is currently blocked on the fix of the unsoundness bug tracked in #120222. The fix is in #120248, but needs a bit more work. I've been occupied by the never type stuff which is urgent because some of the changes are edition based. I hope I'll have time soon to finish #120248.

This is also blocked on rust reference PR, which someone needs to take over: https://github.com/rust-lang/reference/pull/1259#issuecomment-1907299080.

Kish29 commented 2 months ago

It looks like the blocking bug #120222 have been fixed out, and what's next for this stabilization?

WaffleLapkin commented 2 months ago

@Kish29 the next steps are changing the reference (cc https://github.com/rust-lang/reference/pull/1259) and doing a new stabilization PR :)

noclue commented 1 month ago

I am newbie baffled by the absence of this basic syntax. I got this workaround if anyone is interested. It works all on stable Rust

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=0d53066544591aadc71e22bc17f0bb2a