Language inconsistency when implementing a trait

BoxBar<T> in this story is BoxDelta<T>. It's a separate type because it represents the delta between two instances of Box<T>, but is not to be viewed as an instance itself.

In practice it's meant to assist the computation and application of deltas that are derived from types composed of a Box<T> field.

Is there a reason that you've chosen to use BoxDelta<T> instead of Box<DeltaT> or similar?

Yes - Delta's are not simply newtypes as they also encode the possibility of a "null delta" i.e. nothing's changed for that value.

On top of that, it's simpler to keep all Delta types roughly similar in structure - this helps to keep things unsurprising.

It's also true that a custom type restricts what can be done with it.

Do you also have e.g. Delta<T> for owned values? If so why don't you use Box<Delta<T>>?

In another formulation, why is it

impl DeltaOps<T> for Box<T> {
    type Diff = BoxDelta<T>;
}

and not

impl DeltaOps<T: DeltaOps> for Box<T> {
    type Diff = Box<T::Diff>;
}

I just don't see why BoxDelta needs to exist rather than a regular box of a delta.

This discussion has become a bit of a moot point. The original problem was that I couldn't use TryFrom and TryInto because trying to write the relevant impls for Box<T> made rustc complain.

That problem has since been solved by creating my own, specialized conversion traits that do not suffer from the same restriction on Box<T>, i.e. no #[fundamental] attribute on its definition.

The relevant takeaway here is that the combination of TryFrom and TryInto with types marked as #[fundamental] turned out to be more restrictive than I had originally anticipated.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.