よく見たら
impl<T, E> PartialEq<Result<T, E> for Result<T, E>
where T: PartialEq<T>, E: PartialEq<E>
はあるけど、
impl<T, E, U, F> PartialEq<Result<U, F>> for Result<T, E>
where T: PartailEq<U>, E: PartialEq<F>
がないやんけ!!!
そして assert_eq の文脈でこれに躓くの何度目だよ……
https://doc.rust-lang.org/1.71.1/std/result/enum.Result.html#method.as_ref
で、 Result::as_ref() は Result<&T, &E> しか返してくれないので AsRef<U> for T が使えなくて、 Deref<Target=U> for T も意図的に実装を避けているので Result::as_deref() も使えない
仕方ないので
fn ok_as_ref<T, U: ?Sized, E>(res: &Result<T, E>) -> Result<&U, &E>
where
T: AsRef<U>,
{
match res {
Ok(v) => Ok(v.as_ref()),
Err(e) => Err(e),
}
}
みたいなのを用意して、
assert_eq!(ok_as_ref(&foo()), Ok("hello"));
のようにして解決した。あまり愉快ではないが……
assert_eq!(foo().map(AsRef::<str>::as_ref), Ok("hello"));
みたいなのは map でさっさと T が死んでしまって参照が無効になるので駄目