Closed as duplicate of#24066
Closed as duplicate of#24066
Description
I tried this code:
use std::marker::PhantomData;
use std::ops::Deref;
use std::fmt::Debug;
struct Foo {
}
impl Deref for Foo {
type Target=Bar;
fn deref(&self) -> &Self::Target {
todo!()
}
}
struct FooGeneric<V> {
_a: PhantomData<V>,
}
impl<V> Deref for FooGeneric<V> {
type Target=Bar;
fn deref(&self) -> &Self::Target {
todo!()
}
}
struct Bar;
pub trait DerefToBar {}
impl DerefToBar for Bar {}
impl<T> DerefToBar for T
where
T: Deref,
T::Target: DerefToBar
{}
fn require_trait<T>()
where
T: DerefToBar,
{
}
fn test<V>()
where
// Comment this out and rustc is happy.
FooGeneric<V>: Deref,
// Bounds involving totally unrelated traits are fine.
FooGeneric<V>: Debug,
// Explicitly requiring the full recursive trait is fine.
// FooGeneric<V>: DerefToBar,
// Types without a generic param are fine.
Foo: Deref,
{
require_trait::<Foo>();
require_trait::<FooGeneric<V>>();
}
I expect this to compile, but instead rustc can't find a DerefToBar
impl for FooGeneric<V>
, seemingly because it forgets that FooGeneric::Target
is Bar
:
error[E0277]: the trait bound `<FooGeneric<V> as Deref>::Target: Deref` is not satisfied
--> src/lib.rs:62:21
|
62 | require_trait::<FooGeneric<V>>();
| ^^^^^^^^^^^^^ the trait `Deref` is not implemented for `<FooGeneric<V> as Deref>::Target`
|
= help: the trait `DerefToBar` is implemented for `Bar`
note: required for `<FooGeneric<V> as Deref>::Target` to implement `DerefToBar`
--> src/lib.rs:34:9
|
34 | impl<T> DerefToBar for T
| ^^^^^^^^^^ ^
35 | where
36 | T: Deref,
| ----- unsatisfied trait bound introduced here
= note: 1 redundant requirement hidden
= note: required for `FooGeneric<V>` to implement `DerefToBar`
note: required by a bound in `require_trait`
...
error[E0277]: the size for values of type `<FooGeneric<V> as Deref>::Target` cannot be known at compilation time
...
error[E0275]: overflow evaluating the requirement `{type error}: DerefToBar`
I noticed two interesting things here:
- The error disappears if you remove the seemingly harmless explicit
FooGeneric<V>: Deref
bound. - The error doesn't happen for a type without generic parameters, like
Foo
, regardless of explicit bounds.
While the Deref
bound is entirely pointless in test()
, I think that I do need an explicit "induction trait" bound in real life. I can work around it by using the equivalent of a DerefToBar
bound instead, but in the my real case that trait is an implementation detail that I'd like to avoid leaking.
This repros on 1.87 stable (https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=dc207f4b5c603d28024cb0da4fc42d70), though I'm running on nightly.
Meta
rustc --version --verbose
:
rustc 1.87.0-nightly (43a2e9d2c 2025-03-17)
binary: rustc
commit-hash: 43a2e9d2c72db101f5fedac8b3acb78981b06bf2
commit-date: 2025-03-17
host: x86_64-unknown-linux-gnu
release: 1.87.0-nightly
LLVM version: 20.1.0