Post B2wxaFOW4uryIbyplY by hyphen@duwa.ng
 (DIR) More posts by hyphen@duwa.ng
 (DIR) Post #B2sZynZ5VfSjh9G8KO by kookie@chaosfem.tw
       2026-02-01T09:29:58Z
       
       1 likes, 0 repeats
       
       I wish there was a Rust-type-system-y way for a type with a generic T to have (as an  example) two Debug implementations, one for the case that T: Debug and one for when T does not in fact debug.It is kind of a niche problem and I only run into it like once a year. There's some ancient docs that talk about how the specialization feature will fix this but I think that effort has been abandoned due to unsoundness? :akko_badday: I'm curious if anyone #onhere runs has the same cursed problems and if you found a solution you can live with :akko_thonk:
       
 (DIR) Post #B2sZyvYfn5ssUB7unA by kookie@chaosfem.tw
       2026-02-01T09:55:15Z
       
       0 likes, 0 repeats
       
       I guess the easy way is to just enforce T: Debug but I think I will definitely have some Ts that won't be :akko_sad:
       
 (DIR) Post #B2saW3RFVsOeTxRzO4 by hyphen@duwa.ng
       2026-02-01T14:00:44.177534Z
       
       0 likes, 0 repeats
       
       @kookie that's basically haskell's OverlappingInstances right? which is undecidable sure but is it unsound as well?
       
 (DIR) Post #B2wxaFOW4uryIbyplY by hyphen@duwa.ng
       2026-02-03T16:37:57.429425Z
       
       0 likes, 0 repeats
       
       @kookie looked back at this today. it's not a simple overlap because the instance heads are identical, so even haskell and its family would fail here. haskell's solution is a newtype wrapper (as in Monoid Product/Sum) and i guess that's the simplest way (there's also the type family + proxy pattern for a closed sum of instances)...so in rust:struct D<A>(F<A>);impl<A> Debug for D(F<A>) {    fn fmt(&self, f: ...) -> ... {        f.debug_struct("F")         .field("a", format_args!("_"))         .field("x", &self.0.x)         //...         .finish()    }}you could add a const generic phantom type parameter to F itself but that would infect all use sites. you could then write new-style smart constructors to ensure F<A, true> is never constructed with A : ~Debug. in any case this means you'll shift the burden of deciding whether to construct with a constrained A to the user:- #[derive(Debug)]- pub struct F<A> {+ struct F<A, const D: bool = false> {andimpl <A: Debug> Debug for F<A, true> { ... }impl <A> Debug for F<A, false> { ... }andlet a = F(A);// vslet b = F::<_, false>(B);still I think the newtype solution is much better because it only infects the call sites which constrain A.