Skip to content
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

Trait upcasting coercion #98

Closed
crlf0710 opened this issue Jun 15, 2021 · 8 comments
Closed

Trait upcasting coercion #98

crlf0710 opened this issue Jun 15, 2021 · 8 comments
Labels
disposition-merge The FCP starter wants to merge (accept) this final-comment-period The FCP has started, most (if not all) team members are in agreement major-change Major change proposal major-change-accepted Major change proposal that was accepted T-lang to-announce Not yet announced MCP proposals

Comments

@crlf0710
Copy link
Member

crlf0710 commented Jun 15, 2021

Proposal

Summary and problem statement

  • Add the trait_upcasting feature to the language.

Motivation, use-cases, and solution sketches

  • The trait_upcasting feature adds support for trait upcasting coercion. This allows a
    trait object of type dyn Bar to be cast to a trait object of type dyn Foo
    so long as Bar: Foo.
#![feature(trait_upcasting)]

trait Foo {}

trait Bar: Foo {}

impl Foo for i32 {}

impl<T: Foo + ?Sized> Bar for T {}

let foo: &dyn Foo = &123;
let bar: &dyn Bar = foo;

Prioritization

Links and related work

Initial people involved

Also cc @alexreg and @eddyb in case they're interested.

What happens now?

This issue is part of the experimental MCP process described in RFC 2936. Once this issue is filed, a Zulip topic will be opened for discussion, and the lang-team will review open MCPs in its weekly triage meetings. You should receive feedback within a week or two.

This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.

@crlf0710 crlf0710 added major-change Major change proposal T-lang labels Jun 15, 2021
@rustbot
Copy link
Collaborator

rustbot commented Jun 15, 2021

This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.

@rustbot rustbot added the to-announce Not yet announced MCP proposals label Jun 15, 2021
@joshtriplett
Copy link
Member

@rustbot second

@rustbot rustbot added the final-comment-period The FCP has started, most (if not all) team members are in agreement label Jun 22, 2021
@crlf0710 crlf0710 changed the title Trait Upcasting Trait upcasting coercion Aug 20, 2021
@nikomatsakis nikomatsakis added disposition-merge The FCP starter wants to merge (accept) this major-change-accepted Major change proposal that was accepted labels Sep 28, 2021
@nikomatsakis
Copy link
Contributor

This has been seconded and the https://rust-lang.github.io/dyn-upcasting-coercion-initiative/ repository created to track this work!

@JeremyRubin
Copy link

the example seems backwards? should it not be:

#![feature(trait_upcasting)]

trait Foo {}

trait Bar: Foo {}

impl Foo for i32 {}

impl<T: Foo + ?Sized> Bar for T {}

let foo: &dyn Bar = &123;
let bar: &dyn Foo = foo;

where Bar is able to cast up to Foo, as described "trait object of type dyn Bar to be cast to a trait object of type dyn Foo
so long as Bar: Foo.".

Of course, both directions could be possible, but it seems reversed here.

@iddm
Copy link

iddm commented Jun 26, 2022

Is there a workaround until this becomes available?

@JeremyRubin
Copy link

yes, i think casting through a struct should work?

struct CastFoo<'a>(&'a dyn Bar);

impl<'a> Foo for CastFoo<'a> {
  fn fo_every_foo_method(&self, a:Param) -> Output {
    self.0.that_method(a)
  }
}

let bar: &dyn Bar = &123;
let tmp = CastFoo(bar);
let foo: &dyn Foo = &tmp;

@iddm
Copy link

iddm commented Jun 26, 2022

I guess I am doing almost exactly that now. But this code is so ugly that by "workaround" I meant something else :-) Thanks anyway.

@edevil
Copy link

edevil commented Jul 22, 2022

Is there some way to help regarding stabilising this feature?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
disposition-merge The FCP starter wants to merge (accept) this final-comment-period The FCP has started, most (if not all) team members are in agreement major-change Major change proposal major-change-accepted Major change proposal that was accepted T-lang to-announce Not yet announced MCP proposals
Projects
None yet
Development

No branches or pull requests

7 participants