Open
Description
I tried this code:
#![feature(specialization)]
trait Spam {}
trait SpamMore: Spam {}
default impl<T> Spam for T where T: SpamMore {}
struct A;
impl SpamMore for A {}
I expected to see this happen:
An error such as
error[[E0277]](https://doc.rust-lang.org/nightly/error-index.html#E0277): the trait bound `A: Spam` is not satisfied
--> src/lib.rs:9:6
|
9 | impl SpamMore for A {}
| ^^^^^^^^ the trait `Spam` is not implemented for `A`
|
note: required by a bound in `SpamMore`
--> src/lib.rs:4:17
|
4 | trait SpamMore: Spam {}
| ^^^^ required by this bound in `SpamMore`
perhaps with a hint that a default impl
applies, but does not actually fulfill the trait requirement.
Instead, this happened:
Trait requirement evaluation overflowed.
error[[E0275]](https://doc.rust-lang.org/nightly/error-index.html#E0275): overflow evaluating the requirement `A: Spam`
--> src/lib.rs:9:6
|
9 | impl SpamMore for A {}
| ^^^^^^^^
|
note: required by a bound in `SpamMore`
--> src/lib.rs:4:17
|
4 | trait SpamMore: Spam {}
| ^^^^ required by this bound in `SpamMore`
It seems that the compiler sees the obligation A: SpamMore -> A: Spam
, then incorrectly considers the obligation A: Spam -> A: SpamMore
to apply the default impl
... even though a) this is the root bound we're trying to solve for, and more importantly b) the implication A: SpamMore -> A: Spam
doesn't even apply, since default impl
doesn't satisfy the trait without a concrete impl
.
An equivalent pattern using min_specialization
(a default fn
and not default impl
) compiles cleanly:
#![feature(min_specialization)]
trait Spam {
fn f();
}
trait SpamMore: Spam {}
impl<T> Spam for T where T: SpamMore {
default fn f() {}
}
struct A;
impl SpamMore for A {}
Meta
playground 1.63.0-nightly (2022-06-23 4334739)