I think re-rebalancing coherence (RFC#2451) is partially to blame here for the inconsistency. Going back to 1.34.0, when TryFrom was stabilized and re-rebalancing coherence was not yet in, I get a different set of errors that also disallows the impl on Rc:
use std::rc::Rc;
use std::convert::TryFrom;
struct MyRc<T>(Rc<T>);
struct MyBox<T>(Box<T>);
impl<T> TryFrom<MyRc<T>> for Rc<T> {}
impl<T> TryFrom<Rc<T>> for MyRc<T> {}
impl<T> TryFrom<MyBox<T>> for Box<T> {}
impl<T> TryFrom<Box<T>> for MyBox<T> {}
1.41.0 (re-rebalancing coherence)
error[E0119]: conflicting implementations of trait `std::convert::TryFrom<MyBox<_>>` for type `std::boxed::Box<_>`:
--> src/lib.rs:10:1
|
10 | impl<T> TryFrom<MyBox<T>> for Box<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- impl<T, U> std::convert::TryFrom<U> for T
where U: std::convert::Into<T>;
= note: downstream crates may implement trait `std::convert::From<MyBox<_>>` for type `std::boxed::Box<_>`
error[E0119]: conflicting implementations of trait `std::convert::TryFrom<std::boxed::Box<_>>` for type `MyBox<_>`:
--> src/lib.rs:11:1
|
11 | impl<T> TryFrom<Box<T>> for MyBox<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- impl<T, U> std::convert::TryFrom<U> for T
where U: std::convert::Into<T>;
= note: downstream crates may implement trait `std::convert::From<std::boxed::Box<_>>` for type `MyBox<_>`
error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`MyBox<T>`)
--> src/lib.rs:10:6
|
10 | impl<T> TryFrom<MyBox<T>> for Box<T> {}
| ^ type parameter `T` must be covered by another type when it appears before the first local type (`MyBox<T>`)
|
= note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local, and no uncovered type parameters appear before that first local type
= note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
1.34.0 (pre-re-rebalancing coherence)
error: conflicting implementations of trait `std::convert::TryFrom<MyBox<_>>` for type `std::boxed::Box<_>`: (E0119)
--> src\main.rs:10:1
|
10 | impl<T> TryFrom<MyBox<T>> for Box<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[deny(incoherent_fundamental_impls)] on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #46205 <https://github.com/rust-lang/rust/issues/46205>
= note: conflicting implementation in crate `core`:
- impl<T, U> std::convert::TryFrom<U> for T
where U: std::convert::Into<T>;
= note: downstream crates may implement trait `std::convert::From<MyBox<_>>` for type `std::boxed::Box<_>`
error: conflicting implementations of trait `std::convert::TryFrom<std::boxed::Box<_>>` for type `MyBox<_>`: (E0119)
--> src\main.rs:11:1
|
11 | impl<T> TryFrom<Box<T>> for MyBox<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #46205 <https://github.com/rust-lang/rust/issues/46205>
= note: conflicting implementation in crate `core`:
- impl<T, U> std::convert::TryFrom<U> for T
where U: std::convert::Into<T>;
= note: downstream crates may implement trait `std::convert::From<std::boxed::Box<_>>` for type `MyBox<_>`
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
--> src\main.rs:7:1
|
7 | impl<T> TryFrom<MyRc<T>> for Rc<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type
|
= note: only traits defined in the current crate can be implemented for a type parameter
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
--> src\main.rs:10:1
|
10 | impl<T> TryFrom<MyBox<T>> for Box<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type
|
= note: only traits defined in the current crate can be implemented for a type parameter
Ooh, further tidbit: the Box impl used to be allowed, and was deprecated/removed with #46205. That issue contains some further information about why this is incoherent.
So two takeaway points: under rebalancing coherence, both of these cases are disallowed; re-rebalancing coherence allows it for non-fundamental (covering) types. And specialization doesn't even help you at all.
#[fundamental] is inherently about negative reasoning. A #[fundamental] trait can be assumed to not be implemented (e.g. Fn* and Sized) if it is not currently implemented. A #[fundamental] type is slightly different; per my reading of re-rebalancing coherence, a fundamental type's only quality is that its locality is always that of its (singular) type argument, and as such cannot "cover" a type variable.
Without knowing the exact use case of your BoxBar, it's not really possible to suggest other paths. My only suggestion would really be to, if at all possible, use Box<Bar<T>> (where Bar is a repr(transparent) wrapper) rather than a custom box type.