Hi! ![]()
tl;dr: I have two types that are equal according to TypeId but are not equal according to trait resolution.
It looks like I'm breaking something in the type-system with mutual trait-recursion and the specialization feature.
Lengthy details of what I'm trying to achieve
I'm trying to write a compile-time dictionary/map that can map types to integers. I want to be able to add these, element wise. So Dict(A => 3) + Dict(A => 1, B => 2) = Dict(A => 4, B => 2). For that I'm trying to first find the union of all keys: {A, B} and then write a trait/function that can obtain the sum for each key from both dicts to create the final result.
This must be done at compile-time because I want to get compile-time guarantees from it. Specifically I'm looking for something like the uom or dimensioned crate, but with the ability to add quantities/dimensions to a system of quantities without changing all other dimension definitions.
The uom and dimensioned crates realize units using a type a bit like like this:
type Meter = Dimensioned<f64, Length=1, Mass=0, Time=0>;
type Kilogram = Dimensioned<f64, Length=0, Mass=1, Time=0>;
type Time = Dimensioned<f64, Length=0, Mass=0, Time=1>;
type Acceleration = Dimensioned<f64, Length=1, Mass=0, Time=-2>;
When multiplying two numbers you add their dimensions, so acceleration = m/(s^2) = Meter - Time - Time.
I want to achieve the same, but I don't want to fix a specific number of dimensions beforehand, so users can extend the dimensions from outside of the crate, without needing to re-define the entire system of quantities again.
To do that I want to implement essentially a dictionary at a type-system level (with a crappy O(n^2) complexity of adding two dictionaries).
There's two errors:
- from test case 4 where it fails to compute
Test4ListResultbecause a trait bound is not satisfied.
In this error it mentions that
the trait bound
<TArr<B, TArrEnd> as RemoveTypeFromList<A>>::Output: Dedupis not satisfied
However, it does implement Dedup! The linked playground compiles and runs without errors, which means:
a) Test4IntermediateResult and Test4IntermediateExpectedResult are the same type according to TypeId
b) Test4IntermediateExpectedResult implements Dedup
(where Test4IntermediateResult = <TArr<B, TArrEnd> as RemoveTypeFromList<A>>::Output, from the error message above).
- the other error is that
Test4IntermediateResult(which is supposed to be equal toTest4IntermediateExpectedResultand implementsDedup) does not implementDedup
I get that the specializations feature is not ready, but is there anything that can be done here?
What's the reason for this mismatch?
Does the rust compiler not fully evaluate the type of Test4IntermediateResult? Can I tell it to?
Can I achieve my dream of a compile-time dict in a different way?
Thanks for reading, and thanks for any replies and comments in advance! ![]()
ambiso
I think I might want something like Zig's comptime in Rust? Having access to, and being able to compute on types in something like a proc-macro.