diff --git a/crates/fayalite/src/ty.rs b/crates/fayalite/src/ty.rs index ab69532..843aedb 100644 --- a/crates/fayalite/src/ty.rs +++ b/crates/fayalite/src/ty.rs @@ -1309,16 +1309,49 @@ trait TraceAsStringTrait: fmt::Debug + 'static + Send + Sync + SupportsPtrEqWith fn can_substitute_type(&self, new_type: CanonicalType) -> bool; } -impl TraceAsStringTrait for T { +#[derive(Clone, PartialEq, Eq, Hash)] +struct TraceAsStringState { + ty: Interned, + canonical_ty: CanonicalType, +} + +impl TraceAsStringState { + fn new(ty: Interned) -> Interned { + #[derive(Copy, Clone, PartialEq, Eq, Hash)] + struct MyMemoize(PhantomData); + impl Memoize for MyMemoize { + type Input = Interned; + type InputOwned = Interned; + type Output = Interned>; + + fn inner(self, input: &Self::Input) -> Self::Output { + TraceAsStringState { + ty: *input, + canonical_ty: input.canonical(), + } + .intern_sized() + } + } + MyMemoize(PhantomData).get_owned(ty) + } +} + +impl fmt::Debug for TraceAsStringState { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.ty.fmt(f) + } +} + +impl TraceAsStringTrait for TraceAsStringState { fn trace_fmt( &self, opaque: OpaqueSimValueSlice<'_>, f: &mut fmt::Formatter<'_>, ) -> fmt::Result { - fmt::Debug::fmt(&Type::sim_value_from_opaque(self, opaque), f) + fmt::Debug::fmt(&Type::sim_value_from_opaque(&*self.ty, opaque), f) } fn can_substitute_type(&self, new_type: CanonicalType) -> bool { - self.canonical().is_layout_equivalent(new_type) + self.canonical_ty.is_layout_equivalent(new_type) } } @@ -1374,7 +1407,7 @@ impl TraceAsString { Self { inner_ty: LazyInterned::Interned(inner_ty), trace_as_string: LazyInterned::Interned(Interned::cast_unchecked( - inner_ty, + TraceAsStringState::new(inner_ty), |v| -> &dyn TraceAsStringTrait { v }, )), } @@ -1548,7 +1581,10 @@ impl Default for TraceAsStringStaticTypeHelper { impl From> for Interned { fn from(_value: TraceAsStringStaticTypeHelper) -> Self { - Interned::cast_unchecked(T::TYPE.intern_sized(), |v| -> &dyn TraceAsStringTrait { v }) + Interned::cast_unchecked( + TraceAsStringState::new(T::TYPE.intern_sized()), + |v| -> &dyn TraceAsStringTrait { v }, + ) } }