For example, I create some structs that have a field implementing a Trait. I don't want to propagate the dyn
whenever I use this Trait. Any way of removing this?
I want something like pub fn new() -> Y<'a, What>
instead.
For example, I create some structs that have a field implementing a Trait. I don't want to propagate the dyn
whenever I use this Trait. Any way of removing this?
I want something like pub fn new() -> Y<'a, What>
instead.
My first question would be, why do you need to remove the dyn
if you are looking to use it in a const
context?
Also, since you are referencing a const
value, you can just use a 'static
lifetime.
This probably destroys whatever functionality you're after, but does technically remove the dyn
: playground link
Example of the failure:
pub trait What {}
impl What for u8 {}
pub struct Y<'a, W: What + ?Sized> {
a: &'a W
}
impl<'a, W: What> Y<'a, W> {
pub fn new() -> Y<'a, dyn What> {
YIKES
}
}
pub const YIKES: Y<dyn What> = Y {
a: &5
};
pub struct Other<'a, W: What> {
y: Y<'a, W>,
}
impl<'a, W: What> Other<'a, W> {
pub fn new() -> Self {
Self {
y: YIKES
}
}
}
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/lib.rs:26:16
|
23 | impl<'a, W: What> Other<'a, W> {
| - this type parameter
...
26 | y: YIKES
| ^^^^^ expected `Y<'_, W>`, found `Y<'_, dyn What>`
|
= note: expected struct `Y<'a, W>`
found struct `Y<'static, (dyn What + 'static)>`
= help: type parameters must be constrained to match other types
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to previous error
Interesting, this may work. I want an external user to provide the What trait. So I think it could be just a const.
what do you mean? What
is a trait, and a trait is not a type (unlike java or C#), so, Y<'a, What>
is not valid type in rust; on the other hand, dyn What
IS a (unsized) type, so the original code is valid.
if you mean Y<'a, W>
, then it is not not possible, because the trait bounds W: What
provide no means to construct a reference to type W
, which means you have no way to construct a value of the return type (which need a reference to the generic argument W
).
As I see the issue - to make the const
versions you must specify a concrete type. So, when you go to use them, the potential for generic types is already closed off. Thus a function that returns your YIKES
already has a single concrete type.
That being said, this might be closer to useful: playground
Here's a bit more deconstructed version that decouples the type selection, perhaps giving what you're after: playground
Thanks. I'm probably still missing some fundamental understanding that's causing this error:
When you have something like this:
fn example<W: What>(a: u8) -> Container<W> { todo!() }
The caller chooses W
, so you can't return a Container<u8>
-- the caller may have needed a Container<u32>
or some other implementor of What
.
And the same is true here; you're saying you're implementing the function for all Container<W> where W: What
. Self
is an alias for Container<W>
, and the caller gets to choose the W
(so long as the bounds are met). You have to return a Container<W>
, not a Container<u8>
.
impl<W: What> Container<W> {
fn another_one(a: u8) -> Self { todo!() }
}
If we keep going, there's going to be other challenges, like you can't return references to local variables, as those references would immediately dangle.
Also, if I look at these together:
pub trait What {}
impl What for u8 {}
impl What for f32 {}
pub struct Container<W: What + 'static> {
one: u8,
two: u32,
y: &'static W,
}
I get the feeling you're trying to create a self-referencial struct
(where c.y
points to one of c.one
or c.two
). This won't work for a couple reasons:
W
has to resolve to a single type, while one
and two
have different typesFor example you can't move a self-referencial struct, as the reference would dangle.
Thanks for all the help with increasing my understanding, I eventually figured out a solution: WIP: Initial Custom Compression algorithm support by wcampbell0x2a · Pull Request #228 · wcampbell0x2a/backhand · GitHub. Or at least a solution, lmk if I messed something up.
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.