-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Support Trait+Foo
for arbitrary traits
#1277
Comments
A bit more detail? I don't get at all what feature discussions you're referring to. |
Simple example of what we could support: trait Foo { fn foo(&self) {} }
trait Bar { fn bar(&self) {} }
fn f(p: &(Foo + Bar)) {
// Call functions on p.
p.foo();
p.bar();
// Conversions on p.
let p2: &Foo = p;
let p3: &Bar = p;
} Some possible subsets: we might not support the full set of possible conversions. We might restrict what traits this is allowed with. (Special-casing traits without methods is a little dubious: our current API stability rules suggest that you're allowed to add methods with default implementations to existing traits.) Note that this is mostly just syntactic sugar: equivalent example to the above written in stable Rust: trait Foo { fn foo(&self) {} }
trait Bar { fn bar(&self) {} }
trait Baz: Foo + Bar {
fn to_foo(&self) -> &Foo;
fn to_bar(&self) -> &Bar;
}
impl<T> Baz for T where T: Foo + Bar {
fn to_foo(&self) -> &Foo { self }
fn to_bar(&self) -> &Bar { self }
}
fn f(p: &Baz) {
// Call functions on p.
p.foo();
p.bar();
// Conversions on p.
let p2: &Foo = p.to_foo();
let p3: &Bar = p.to_bar();
} |
👍 |
👍*2 |
|
I have been thinking that On Wed, Sep 23, 2015 at 8:49 PM, withoutboats notifications@github.com
|
I'd think that whatever change we get to support upcasting would also enable the subset-taking for a single-vtable |
@Kimundi We can support arbitrary subset-taking without using multiple
The same is basically true for upcasting. That is, if you have:
and you want to allow On Thu, Oct 1, 2015 at 6:23 AM, Marvin Löbel notifications@github.com
|
@nikomatsakis (Just thinking aloud) if the vtable for (You can make sure it's order independent i.e.
How would multiple vtables work here? Would |
yeah, you're right that we can get some reduction this way. But bottom line is it is still a "lot" of vtables. :)
I think that the vtable for the trait
|
Oh, hmm... that's the other option I was thinking about but couldn't immediately figure out how that would allow subset-taking - but I guess you'd just read out the supertrait vtable pointers from the subtrait vtable and make the fat pointer using them? The other objection I had in mind was that this would make method calls require as many indirections as the inheritance hierarchy is deep, which doesn't seem like it would be in the spirit of Rust's performance philosophy, but I guess you could solve that as well by in addition also embedding the supertrait vtables directly into the subtrait vtable? Though in that case, you don't even need the extra vtable-pointers any more... even with |
Yes, which is what we do today. And yes, you may be able to make some of the vtables subsets of one another, just as you observed for the EDIT: Well, more-or-less the same problem. C++ isn't trying to have types like |
To be clear, what I was trying to say is that you could have it so that:
|
Ah. This is basically precisely what I had in mind, yes, when I proposed On Thu, Oct 1, 2015 at 5:10 PM, Gábor Lehel notifications@github.com
|
True, if we are talking about arbitrary susbsets you get some exponential blowup if you want to generate a vtable for each subset. Just another idea, but one possible way to mitigate that could be to create a single big vtable that is the merge of all However, the multiple-vtable-pointer approach is certainly the simplest, and I'd like to see it implemented simply because it would set the precedence of As an aside, I'm also wondering wether any of these approaches would prevent upcastability from |
Yeah. I'm not sure what else we might use that concept for, but at minimum
I think it should be fine, as Gábor described. On Fri, Oct 2, 2015 at 5:28 AM, Marvin Löbel notifications@github.com
|
Some additional examples that come to mind:
|
sort of unformed ideas for how to implement this:
probably there is prior art for this. But I'm unhappy with solutions that take advantage of the knowledge that |
Closing in favor of #2035. |
@nikomatsakis has mentioned wanting to write a complete RFC for this. He has also mentioned that a weaker form of this proposal might be easier to produce, where instead of supporting
Trait+Foo
for any arbitrary trait we support it only for "marker traits", i.e. traits without methods.Blocking rust-lang/rust#28326
The text was updated successfully, but these errors were encountered: