Closed
Description
Original discussion: https://users.rust-lang.org/t/unexpected-behaviors-of-trait-bounds/12286/10
Looks like it's related to this old issue: #29859
Basically, having trait Complete
require trait Partial
, and trait Partial
require trait PartialEq
(or any other trait), a type (struct TypeB
) with impl Complete
doesn't need to satisfy impl PartialEq
, which only looks like a bug.
Interestingly, whenever <TypeB as Partial>
is seen, the check is performed and appropriate error is thrown.
Here's a repro:
pub trait Partial: PartialEq {
fn foo() -> Option<bool>;
}
pub trait Complete: Partial {
fn foo() -> bool;
}
impl<T> Partial for T
where
T: Complete,
{
fn foo() -> Option<bool> {
Some(<Self as Complete>::foo())
}
}
// ----
#[derive(PartialEq)]
pub struct TypeA {}
impl Partial for TypeA {
fn foo() -> Option<bool> {
None
}
}
// ----
// BUG: No compile warning about `PartialEq` not being implemented
// #[derive(PartialEq)]
pub struct TypeB {}
impl Complete for TypeB {
fn foo() -> bool {
true
}
}
// ----
pub fn main() {
println!("{:?}", TypeA::foo());
// This works, but shouldn't!
println!("{:?}", <TypeB as Complete>::foo());
// This would trigger the issue, though.
//println!("{:?}", <TypeB as Partial>::foo());
/* Result in:
error[E0277]: the trait bound `TypeB: std::cmp::PartialEq` is not satisfied
--> src/bin/cyclic_traits.rs:48:22
|
48 | println!("{:?}", <TypeB as Partial>::foo());
| ^^^^^^^^^^^^^^^^^^^^^^^ can't compare `TypeB` with `TypeB`
|
= help: the trait `std::cmp::PartialEq` is not implemented for `TypeB`
= note: required by `Partial::foo`
*/
}