Open booti386 opened 1 year ago
I believe this problem looks like
pub trait B<I, O> {}
impl<T, I: ExternNotVoid> B<I, ()> for T {} // Generic over B<I, ()>
impl<T, O: ExternNotVoid> B<(), O> for T {} // I is generic,
// and () is !ExternNotVoid, so it can't be in I
// but that isn't factored into checking the validity of the implementation
I'm not sure which is the "intended" behavior. But I believe this is a known issue? There are several issues regarding negative impls, coherence-checking, their interaction with auto-traits, and their soundness:
At a glance, none seem like an exact match, but it could just be my inability to perceive a pattern where one exists.
What particularly surprises me is that it works when everything is in the same crate, but stops working when NotVoid is declared in another crate.
A crate is allowed to bend the rules slightly for its own trait-and-type implementations (due to not being subject as directly to the "orphan rule"). I'm not sure this case of such a weakening is sound (or due to the orphan rule and related coherence checks, for that matter).
I tried this code:
I expected to see this happen: Identical behavior when
NotVoid
is declared in an external crate.Instead, this happened:
An error is produced when
NotVoid
is declared in an external crate (ExternNotVoid
).Meta
rustc --version --verbose
: