TAIT coherence checks don't ensure composability of crates #130978
Labels
A-coherence
Area: Coherence
A-trait-system
Area: Trait system
C-bug
Category: This is a bug.
F-type_alias_impl_trait
`#[feature(type_alias_impl_trait)]`
requires-nightly
This issue requires a nightly compiler in some way.
T-types
Relevant to the types team, which will review and decide on the PR/issue.
The coherence checks for trait implementations where the receiver type is an opaque type (defined with TAIT) are designed and/or implemented in a way that doesn’t uphold the principle of seamless composability of crates. It also doesn’t uphold current principles of what kind of trait implementation constitutes a breaking change.
Here’s a reproducing example (consisting of 3 crates):
crate A
crate B
crate C
The above example involving 3 crates A, B, C; A is a dependency of B and C.
C compiles successfully with just A as a dependency.
If B is added as a dependency of C (and actually used, by uncommenting the
use b;
) then the following error appears:The error also does make sense: If we further change crate C, so that the defining use of
Alias
produces not aFoo
but ab::Wrapper<Local>
, then theimpl
s ofMyFrom
will become actually overlapping, even when the opaque type is treated transparently. As far as I can tell, it seems that the goal of the error was to be conservative and ensure that changing the actual concrete choice of type behind the opaque TAIT-type should not introduce any new overlap errors later.As a consequence, in my opinion this means that without the crate B, there should probably also be some kind of error here.
Some more thoughts and observations:
impl<T> MyFrom<T> for Wrapper<T>
is a blanketimpl
. Addition of such an impl is actually considered a breaking change in other kinds of situationsimpl
is added for a typeWrapper<T>
that already exists in previous versions, that’s considered technically breakingWrapper<T>
, that it okay; and it’s exactly this combination that “add trait B as dependency” achievesimpl<T> MyFrom<T> for Wrapper<T>
produces the same error if crates A and B are combined into one. I split them up, because it makes an even stronger argument; nonetheless, common “what’s considered breaking” standards imply that crate A should of course also be allowed to simply add such a pair of structWrapper<T>
+ thisimpl
ofMyFrom
, and this issue violates that principle, too.From
andAsRef<str>
results in an error mention that surprisingly mentions random stuff such asgimli::common::DebugFrameOffset
[presumably because it’s the first type the compiler finds that has some kind ofFrom<T> for Self<T>
-style implementation]. If nothing else that’s a surprising diagnostic, but unsurprisingly is just highlighted this more abstract&general issue with coherence-checks.@rustbot label +F-type_alias_impl_trait +A-coherence +A-traits +T-types
The text was updated successfully, but these errors were encountered: