Force use of type alias in type hint inlays

I am looking to create something similar to the dimensioned crate using a concept similar to what is offered by the typenum crate. Because I only need a small piece of the functionality of both crates, I am re-implementing a simplified version of them for my own team. The point is to keep track of dimensions of mathematical computations at compile-time. I have created type aliases for common dimensions.

The problem I am running into is that my IDEs (RustRover and VSCode) provide type hints using the original types rather than the aliased ones-- see screenshots. For example, the type hint for my_time is Dimensions<Z0, P1, Z0> instead of Time, etc. I understand this behavior is the pragmatic one: there could be more than one alias pointing to the same type, so there might be a possible ambiguity. But in may case this will not happen.

What options (hacks / forking are acceptable as last resort) do I have to manually indicate to my IDEs what hint to display for the inlays? I am happy to create a dedicated mapping from Dimensions<...> to the alias for the IDEs to use.

Here is a (somewhat) minimal working example of what I'm trying to do:

use std::marker::PhantomData;
use std::ops::{Add, Mul, Sub};

trait TypeNumAdd<N2> {
    type Output;
}

struct N1;
struct Z0;
struct P1;

impl TypeNumAdd<N1> for Z0 {
    type Output = P1;
}

impl TypeNumAdd<N1> for P1 {
    type Output = Z0;
}

impl TypeNumAdd<Z0> for N1 {
    type Output = N1;
}

impl TypeNumAdd<Z0> for Z0 {
    type Output = Z0;
}

impl TypeNumAdd<Z0> for P1 {
    type Output = P1;
}

impl TypeNumAdd<P1> for N1 {
    type Output = Z0;
}

impl TypeNumAdd<P1> for Z0 {
    type Output = P1;
}

pub struct Null;

#[repr(transparent)]
pub struct Dimensions<L, T, M, Ind = Null>(
    f64,
    PhantomData<(L, T, M, Ind)>
);

impl<L, T, M, Ind> From<f64> for Dimensions<L, T, M, Ind> {
    fn from(value: f64) -> Self {
        Dimensions(value, PhantomData)
    }
}

impl<L, T, M, Ind> Copy for Dimensions<L, T, M, Ind> {}
impl<L, T, M, Ind> Clone for Dimensions<L, T, M, Ind> {
    fn clone(&self) -> Self {
        Dimensions(self.0, PhantomData)
    }
}

impl<L, T, M, Ind> Add for Dimensions<L, T, M, Ind> {
    type Output = Self;
    fn add(self, rhs: Self) -> Self::Output {
        Dimensions(<f64 as Add>::add(self.0, rhs.0), PhantomData)
    }
}

impl<L, T, M, Ind> Sub for Dimensions<L, T, M, Ind> {
    type Output = Self;
    fn sub(self, rhs: Self) -> Self::Output {
        Dimensions(<f64 as Sub>::sub(self.0, rhs.0), PhantomData)
    }
}

impl<L1, T1, M1, Ind, 
    L2, T2, M2,
    L3, T3, M3> Mul<Dimensions<L2, T2, M2, Null>> for Dimensions<L1, T1, M1, Ind>
where 
    L2: TypeNumAdd<L1, Output=L3>,
    T2: TypeNumAdd<T1, Output=T3>,
    M2: TypeNumAdd<M1, Output=M3>
{
    type Output = Dimensions<L3, T3, M3, Ind>;
    fn mul(self, rhs: Dimensions<L2, T2, M2, Null>) -> Self::Output {
        Dimensions(<f64 as Mul>::mul(self.0, rhs.0), PhantomData)
    }
}



type Speed = Dimensions<P1, N1, Z0>;
type Length = Dimensions<P1, Z0, Z0>;
type Time = Dimensions<Z0, P1, Z0>;

#[test]
fn my_test() {
    let my_time = Time::from(6.53);
    let my_speed = Speed::from(1.2);
    
    let result = my_time * my_speed;
}

A similar question was asked recently:

I think the screenshots are missing.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.