When using a trait which is constrained by some bounds, and is implanted automatically for types satisfying those bounds (seen often as the equivalent of type alias in traits), the compiler can run into overflow evaluating bound requirement, which only happen with the helper trait (and not the full bound),
I tried this code:
use std::marker::PhantomData;
trait Hello<'a> {
type Value;
}
struct Wrapper<T>(PhantomData<T>);
impl<'a, T1, T2> Hello<'a> for Wrapper<(T1, T2)>
where
Wrapper<T1>: Hello<'a, Value = T1>,
Wrapper<T2>: Hello<'a, Value = T2>,
{
type Value = (T1, T2);
}
impl<'a> Hello<'a> for Wrapper<u32> {
type Value = u32;
}
/// The helper trait
trait Helloable: Sized
where
Wrapper<Self>: for<'a> Hello<'a, Value = Self>,
{
}
impl<T> Helloable for T where Wrapper<T>: for<'a> Hello<'a, Value = Self> {}
// compiles
fn test1<T>()
where
Wrapper<T>: for<'a> Hello<'a, Value = T>,
{
}
// overflow error
fn test2<T>()
where
T: Helloable,
{
}
I expected to see this happen: This code should compile, with both test1 and test2 (or at the very least not compile with either one).
Instead, this happened: This code compiles with test1, but adding test2 causes an overflow in the tuple implementation and prevents the code from compiling (even though the two functions are practically with the same bounds).
Meta
This happens on all channels (as can be seen in the playground), but here is the local nightly compiler I tried debugging this with:
When using a trait which is constrained by some bounds, and is implanted automatically for types satisfying those bounds (seen often as the equivalent of type alias in traits), the compiler can run into overflow evaluating bound requirement, which only happen with the helper trait (and not the full bound),
I tried this code:
playground link
I expected to see this happen: This code should compile, with both
test1
andtest2
(or at the very least not compile with either one).Instead, this happened: This code compiles with
test1
, but addingtest2
causes an overflow in the tuple implementation and prevents the code from compiling (even though the two functions are practically with the same bounds).Meta
This happens on all channels (as can be seen in the playground), but here is the local nightly compiler I tried debugging this with:
rustc --version --verbose
:For the curious, this structure of code arose from trying to work with serde's
DeserializeSeed
, which in this example I replaced with the traitHello
.