As we don’t have #[feature(unsized_locals)] before, we don’t want to allow dyn Into<T> because it will be useless.
Once we allow object safe methods to receive self by value, the reason above disappears.
Enabling dyn Into<T> on the other hand, enables a lot of new abstractions to appear, and it can be seen as Rust’s standard representation of lazy evaluations. For example, we can image the short circuit boolean operation being defined as
trait And<Rhs=Self> {
type Output;
fn and(self, rhs: dyn Into<Rhs>) -> Self::Output;
}
impl And for bool {
type Output = bool;
fn and(self, rhs: dyn Into<bool>) -> bool {
if self { return true } else { rhs.into() }
}
}
(The above is not implied in this RFC, only demonstrates future improvement possibilities).
(However, many other traits in std::ops can be relaxed like this, I am not sure shall I included them as well.)
This would require unsized rvalues, which is currently in the works. There is no other way to make this change, because changing the signature of Into would be a breaking change. Currently this is impossible to do.
Yes, it has been accepted, but right now it isn’t implemented, so it may take a while to get it. Also just because a RFC gets accepted, doesn’t mean it will get stabilized (see placement new). That said, I doubt unsized rvalues will be unaccepted.
Ok. But as long as we know that into is callable when dyn Into do exist, it is still already possible to use dyn Into right? So I didn’t see a reason to stop this. Maybe the And example I gave is too early and require something else, but making dyn Into usable is already implemented.
I’m not trying to stop this (I probably could have communicated that better), I just want it noted that this pre-RFC will depend on something which is currently not even implemented (unsized rvalues). Also, currently it would not be possible to call into if we had a dyn Into because Self is dyn Into, which is !Sized. !Sized values cannot be used on the stack, because their size is unknown at compile time and because of this we cannot initialize the self parameter of into. Due to this, it is impossible to call into without unsized rvalues (which will allow !Sized values on the stack) or a change to into's signature (which not an option due to stability concerns).
I am not sure. But I think it is not likely, as we don't have negative trait bounds yet.
I think for the type T it is implied to be Sized, but not for Self. However, the source code explicitly requires Self: Sized and this is what I want to change.
Negative trait bounds would make adding a trait a breaking change. Removing a trait bound for a trait could be a breaking change. For example say (in some crazy world) we remove the trait bound Clone for Copy. Any code that relies on the fact the every type that implements Copy also implements Clone would break. But with the Sized trait I'm not so sure because it is the default and it is auto-implemented.
So yes, I think removing a Sized trait bound is technically a breaking change, though I have no idea if this would come up in a more realistic scenario.