Hello! First time poster here, I hope this isn’t off-topic. Someone on #rust-beginners said I should post this here.
To refresh my understanding of how dynamic dispatch works in Rust, I wrote some sample code roughly:
let mut my_vec: Vec<Box<MyTrait>> = Vec::new()
my_vec.push(Box::new(Foo{}));
my_vec.push(Box::new(Bar{}));
my_vec.push(Box::new(Baz{}));
Seeing all that repeated Box::new(…) boilerplate, I thought hey, I’ll just write a trait that’ll do that for me so that I can push things that implement a trait into a Vec<Box<ThatTrait>>
. That lead to the following conversation:
23:54:08 NfNitLoop | Can generic parameters not refer to traits? I'm trying to implement a method for
| Vec<Box<SomeTrait>> that will accept T:SomeTrait, but it doesn't like using SomeTrait
| in the where clause.
23:54:10 NfNitLoop | https://is.gd/jpI5iV
23:55:50 scottmcm | NfNitLoop: there are only generic type parameters, not generic trait parameters
23:56:22 scottmcm | NfNitLoop: so in `impl<Trait, T>` Trait is a type, not a trait, and thus it can't be
| used in a bound
23:57:04 robrob | this works: https://is.gd/AV0wj3 but not sure what you intended
23:57:50 NfNitLoop | Yeah, I don't want it bound to a single trait, though.
23:58:15 NfNitLoop | I want to say, for all Vec<Box<Foo>> (where Foo is a trait), let me push(T) where T
| implements trait Foo.
23:59:33 robrob | i think this only works for static traits
23:59:43 NfNitLoop | What's a static trait?
23:59:52 * | NfNitLoop googles.
23:59:59 scottmcm | NfNitLoop: https://is.gd/WXaBFB
00:00:07 robrob | a trait known at compile-time I mean
00:01:04 NfNitLoop | scottmcm: aha. that works.
00:01:31 scottmcm | NfNitLoop: it doesn't require heterogeneity, though
[...]
00:02:30 NfNitLoop | scottmcm: doesn't *require* it, but it allows it, no?
00:02:36 scottmcm | NfNitLoop: I'm still checking that :P
00:04:03 NfNitLoop | Oh, no, it doesn't.
00:04:14 scottmcm | Yeah, into isn't as magical as I wanted.
00:04:15 NfNitLoop | It just pushes the problem one further down the chain.
00:04:18 scottmcm | Time to try something else...
[...]
00:17:10 scottmcm | NfNitLoop: hmm, I can't seem to find the constraint that will let me turn Box<T> into
| Box<Trait>
00:17:25 scottmcm | If they're concrete it's a coersion, but I don't know what the method should be.
00:19:34 scottmcm | NfNitLoop: https://is.gd/imbYaQ <-- that works, but it's odd that I needed to impl
| From myself
00:24:04 bluss | scottmcm: T: Trait is all that's needed (and it coerces)
00:24:21 bluss | scottmcm: I guess it only got harder to use .into()
00:24:47 scottmcm | bluss: Trait is a generic parameter, though, so it's not usable as a bound?
00:25:04 bluss | scottmcm: oh that's a lot more interesting. You're right
00:26:30 scottmcm | bluss: yeah, that's why it got weird. There isn't a trait to bound to for that
| coersion, right?
00:29:03 NfNitLoop | scottmcm: Yeah, having to implement From is just pushing the need to do an impl per
| trait down another level. I'd love to avoid that if possible. :)
00:29:52 scottmcm | NfNitLoop: yeah, the updated one just has a simpler impl than the last one :|
00:32:05 scottmcm | But this new requirement is something that might be reasonable to have std provide,
| since most coersions are available via Into. Maybe start an IRLO thread?
The code samples we were discussing should still be live at those rust playground links.
Is there a way to do this currently without resorting to writing an impl for every trait? Should there be?
Thanks!