Closed
Description
I'm trying to write Debug impls for the yoke
crate:
Non-compiling code
use std::borrow::*;
use std::fmt;
pub trait Yokeable<'a>: 'static {
type Output: 'a;
}
impl<'a, T: 'static + ToOwned> Yokeable<'a> for Cow<'static, T> {
type Output = Cow<'a, T>;
}
pub struct Yoke<Y: for<'a> Yokeable<'a>> {
y: Y
}
impl<Y: for<'a> Yokeable<'a>> Yoke<Y> {
pub fn get<'a>(&'a self) -> &'a <Y as Yokeable<'a>>::Output {
unimplemented!()
}
}
impl<Y> fmt::Debug for Yoke<Y> where Y: for<'a> Yokeable<'a>, for<'a> <Y as Yokeable<'a>>::Output: fmt::Debug {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.get().fmt(f)
}
}
// impl<Y> fmt::Debug for Yoke<Y> where Y: for<'a> Yokeable<'a>, for<'a> &'a <Y as Yokeable<'a>>::Output: fmt::Debug {
// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// self.get().fmt(f)
// }
// }
fn format_yoke(x: Yoke<Cow<'static, u8>>) {
println!("{:?}", x)
}
(playpen)
This code fails to compile:
error[E0277]: `<std::borrow::Cow<'_, u8> as Yokeable<'a>>::Output` doesn't implement `Debug`
--> src/main.rs:35:22
|
35 | println!("{:?}", x)
| ^ `<std::borrow::Cow<'_, u8> as Yokeable<'a>>::Output` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= help: the trait `for<'a> Debug` is not implemented for `<std::borrow::Cow<'_, u8> as Yokeable<'a>>::Output`
= note: required because of the requirements on the impl of `Debug` for `Yoke<std::borrow::Cow<'_, u8>>`
= note: required by `std::fmt::Debug::fmt`
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
However, swapping the for<'a> <Y as Yokeable<'a>>::Output: fmt::Debug
bound with for<'a> &'a <Y as Yokeable<'a>>::Output: fmt::Debug
has it start compiling again.
Compiling code
use std::borrow::*;
use std::fmt;
pub trait Yokeable<'a>: 'static {
type Output: 'a;
}
impl<'a, T: 'static + ToOwned> Yokeable<'a> for Cow<'static, T> {
type Output = Cow<'a, T>;
}
pub struct Yoke<Y: for<'a> Yokeable<'a>> {
y: Y
}
impl<Y: for<'a> Yokeable<'a>> Yoke<Y> {
pub fn get<'a>(&'a self) -> &'a <Y as Yokeable<'a>>::Output {
unimplemented!()
}
}
// impl<Y> fmt::Debug for Yoke<Y> where Y: for<'a> Yokeable<'a>, for<'a> <Y as Yokeable<'a>>::Output: fmt::Debug {
// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// self.get().fmt(f)
// }
// }
impl<Y> fmt::Debug for Yoke<Y> where Y: for<'a> Yokeable<'a>, for<'a> &'a <Y as Yokeable<'a>>::Output: fmt::Debug {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.get().fmt(f)
}
}
fn format_yoke(x: Yoke<Cow<'static, u8>>) {
println!("{:?}", x)
}
(playpen)
Note that Yoke::get()
does not need to exist to reproduce this bug, however it helps motivate why an HRTB bound is necessary.
It seems like both cases should successfully compile, all Cow<u8>
s implement Debug.