At the moment, Rust has a TryFrom<Box<[T]>> for Box<[T; N]>
impl, but the reverse does not seem to work.
If we decide this is a good thing to add, I'd be happy to write it.
At the moment, Rust has a TryFrom<Box<[T]>> for Box<[T; N]>
impl, but the reverse does not seem to work.
If we decide this is a good thing to add, I'd be happy to write it.
You can already convert a Box<[T; N]>
to a Box<[T]>
through unsize coercion (playground example)
I think a From
impl would still be usefull when used in generics
You're right; Intellij Rust has led me astray. I'll file that as an issue there.
We aren’t having From
implementations for Box<SomeType>
to Box<dyn SomeTrait>
either. Or for &[T; N]
to &[T]
. Adding From<Box<[T; N]>> for Box<[T]>
might be a bit arbitrary.
I'd argue that conversion is reasonable as well.
The one thing that would put a stopper in all 3, though. IIRC [T;N] is a fundamental type, as is &T and Box, so the stdlib can't add a blanket impl for those conversions as a user crate could individually impl From<Box<[LocalType;N]>> for Box<[LocalType]>
, and stdlib adding impl<T,const N: usize> From<Box<[T;N]>> for [T]
would break that.
No, arrays are not fundamental types, quite the opposite, they're always treated as foreign types, just like slices, so neither Box<[LocalType;N]>
nor Box<[LocalType]>
can be considered local, and that impl is impossible to write.
Ah, that makes sense (otherwise, the TryFrom expansion couldn't happen). That should solve that problem, probably.
In any case, I think that more coercions should be available as a trait. In generic contexts it can be overly annoying to cause a coercion to happen. I had an issue when trying to validate the signature of fn-items before type-erasing them into a syscall array with a macro, in that I couldn't without writing the signature... Although I guess that From/Into wouldn't solve that issue, but my point stands. Coercing types in generic contexts requires forcing a coercion, and .from() is nicer than as ...
or if true{x}else{something else that forces the coercion}
. However, it may be better to add a Coercion
trait that can be used to generically perform static coercions. That would also allow trait objects, which I know are local to the trait's crate, to receive these generic impls. It could also use an associated type, which is more useful in a generic context (as I do not believe that T: Into<U>
allows inferring U).
Don't we already have Unsize
and CoerceUnsized
?
A few reasons that isn't useful in this case:
[T;N]
case.CoerceUnsized
and Unsize
are unstable, and seem to be implementation details.CoerceUnsized
has the same deficiences as Into
, in that you can't infer the U
in a generic context. It's also strictly worse, because there isn't (yet) a way to force it to perform the coercion without writing a cast or using if{...}else{...}
.I think there's a reason coercions don't apply in generic contexted, and that's because it would be confusing to know what's the generic type. Yes, we already have autoref/autoderef that does something like that, and it has been proven to be confusing.
Also, CoerceUnsized
is generic because it has to be. A non-generic version could work for [T; N]
, but not for trait objets, since Box<MyType>
can be coerced to both Box<dyn Foo>
and Box<dyn Bar>
(if MyType
implements Foo
and Bar
).
I guess that's true, so a non-generic would have to be something more like Decay
, that's implemented for Pointers to Arrays, and fn-items to fn-ptrs, but not to trait objects. I still think it would be a good idea to have, because it gives even an explicit way to cause a coercion in a generic context. It may be difficult (to impossible) to allow implicit coercions in a generic context, but there should be a way to cause a coercion explicitly in such a context (even if you may not know the actual type you need to coerce to).
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.