Blanket implementation for `impl<T, U: Into<T>> Into<Option<T>> for Option<U>`

Why doesn't the standard library have a blanket implementation for impl<T, U: Into<T>> Into<Option<T>> for Option<U>?

It's rather inconvenient that there is no Into<Option<B>> for Option<A> when there is an Into<B> for A, as this tends to make Options less convenient in some scenarios (e.g. macros that expect there to exist an Into, but you have to use Option<B> instead of B and therefore there is no Into even though it could have existed).

1 Like

This implementation would overlap with the generic impl<T> From<T> for T implementation, and thus be rejected by the compiler. Feel free to try it yourself :slight_smile: Option is re-defined easily enough as enum Option<T> { None, Some(T) }

1 Like

Could specialization work around that?

Specialization is currently not used in order to write public, otherwise impossible trait implementations. The standard library only uses it for performance optimizations that could – at least in principle – all still be removed if necessary.'

See also this relatively recent similar topic: impl<T, U: From<T>> From<Vec<T>> for Vec<U> - #7 by scottmcm

Maybe specialisations should be used for this then? Is there any good reason specialisation shouldn't be used for this?

My interpretation of the situation would be: specialization is a severely incomplete language feature with a lot of hard unsolved design issues. Nobody knows what specialization will look like when (if?) it ever gets stabilized in any form; and consequently nobody knows what use-cases exactly will be supported by any future actual specialization feature. It thus would be too strong a commitment to use the flawed status-quo of specialization in order to implement trait implementations in ways that – however desirable they may be in principle [1] – might never be supported. Once such a trait implementation would be offered, Rust’s stability means it’s a commitment to support it indefinitely.

Incidentally, even the current flawed specialization feature can not (or was it possible, but complicated?) support overlapping implementations where one is not strictly more concrete than the other. The generic impl<T> From<T> for T and a impl<V: From<U>, U> From<Option<V>> for Option<T> overlap for the case T == Option<U> == Option<V>, U == V, but both cover cases the other one doesn’t cover.

That being said, this is only my personal take. Probably somewhere (though I don’t know where exactly) there’s existing discussions presenting the “official” reason for why we don’t expose specialization in public trait implementations of the standard library.


  1. though in this case, as From and Into are merely convenience traits anyways, there isn’t even a particularly strong argument to begin with why we would absolutely need the trait implementation in question ↩︎

6 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.