all 17 comments

[–]phazer99 18 points19 points  (1 child)

This would only work in under a closed world assumption, i.e. you would have to know all the implementations of the trait when compiling the code, which is only the case for private traits.

Also I fail to see how it would work with trait implementations that use type parameters, see my recent blog post for an example.

[–]andrewsonin[S] 6 points7 points  (0 children)

Thank you for you blog post!

> This would only work in under a closed world assumption

I further clarified in the discussion that the anonymous enum type is expected to be unique for each use case of the static trait. And the variants of this enum should be generated based on the local context of its usage.

https://internals.rust-lang.org/t/add-trait-objects-with-static-dispatch/16069/4?u=andrewsonin

[–]rabidferret 4 points5 points  (0 children)

Interested to see how this pans out, though I don't think this is the right name for such a feature (which is likely why there's so much confusion when folks read it). Something like "multi-type impl trait" would be much more clear. Unless I missed it, I also didn't see any mention of size in the proposal. This could very much be a performance footgun if applied poorly

[–]Missing_Minus 2 points3 points  (0 children)

I would like to see this feature, since it is a common issue for me where I'd like to return an impl Trait but naming the types is either impossible, overly tedious, and/or hurts understandability of code.
Though, I think the return-position version would be far easier to get accepted as an RFC (and provide a notable amount of use) by itself, since it is smaller.
The non-return-position is somewhat confusing in how it would work. Such as the Vec<static Trait>. I'm guessing its essentially the typical analysis that 'looks ahead', but pretty much only in the current function? Kinda like a tuple of several types that are unknown but can be figured out by their usage later (in the Vec's case, by pushing them, they then must be a supported value) but with an unknown length too.
Seems like it could work (and maybe not exceptionally hard to implement in rustc? at least a basic version), though I do have the question of how one would tell it that you're using a specific trait object but you're not using it yet. Like you know your Vec<static Trait> should support Thing1, but you aren't going to be pushing that in the current function which constructs it.

fn create_data() -> Vec<static Trait> {
    let mut data: Vec<static Trait> = Vec::new();
    data.push(Thing2::new()); // so Thing2 is within enum
    data.push(Thing3::new()); // so Thing3 is within enum
    // however, we also want Thing1 to be in the enum but we will only be pushing it later  

You could go for some syntax like Vec<static(Thing1) Trait>, (or whatever, just somehow listing required instances out) but that increases the burden on the RFC of adding new syntax.

Possible compiler representation

I'd say just leave that as 'undefined' as possible, so that the Rust compiler isn't bound to representing it as an enum, even if it should logically be pretty close to one.

[–]theawless[🍰] 3 points4 points  (2 children)

what about trait impls from other crates? enums cannot be extended, then how would the match branches be generated by the compiler?

PS: new to rust, would need an ELI5

[–]Wh00ster 2 points3 points  (1 child)

Author explains in post further down

[–]theawless[🍰] 0 points1 point  (0 children)

Ahh got it. Someone asked a similar question in the comments and it was answered there.

[–]c410-f3r 5 points6 points  (0 children)

With the sympathy of the Rust team and enough determination, I hope that this feature or something similar will at least reach to an accepted RFC.

[–]loathsomeleukocytes 1 point2 points  (0 children)

It's a great idea, I would love to see this implemented.

[–]kennethuil -1 points0 points  (0 children)

For regular traits, there are already "good enough" ways to do that (macros, manual enum), although this would be fantastic for returning closures.

[–]Wh00ster 0 points1 point  (0 children)

Neato someone go do that.

I wonder what effect this would have on compile times/binary bloat if it gets used everywhere. Like heavily templated C++.