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.