Is there a way to cache an intermediate reference to a value

struct Vehicle { }

struct Car<'a> {
    base: &'a Vehicle,
}

struct Truck<'a> {
    base: &'a Vehicle,
}

impl Vehicle {
    pub fn as_car(&self) -> Car {
        do_compelx_and_heavy_verify();

        Car { base: self, }
    }

    pub fn as_truck(&self) -> Truck {
        do_compelx_and_heavy_verify();

        Truck { base: self, }
    }
}

fn do_compelx_and_heavy_verify() { }

Car and Truck contain inner references to Vehicle. To generate the references, we have to take some dirty and slow verifications on Vehicle, and that is time-consuming.

I want to cache the result of such an intermediate type, Car or Truck, and hide the Vehicle type somewhere.

I have tried to wrap these two types in a single struct but failed due to lifetime conflict.

And, it is an obvious error if I totally ignore the vehicle and hold a car only.

Are there some best practices to handle such a situation with cached intermediate Car or Truck?

What you wrote compiles, so I don't quite understand what you're trying to do.

If you mean, hold a Car (or Truck) in the same struct as the underlying Vehicle, that would be a self-referencial struct. There are no easy ways to deal with those.

Perhaps you want something more like an owning wrapper / type state you can switch between.

struct CarData{}
struct VehicleData {}
struct Vehicle {
    data: VehicleData,
    maybe_car: Option<CarData>,
}

struct Car {
    base: Vehicle, // or maybe VehicleData
    data: CarData,
}

impl Vehicle {
    pub fn into_car(mut self) -> Car {
        let data = self.maybe_car.take().unwrap_or_else(
            || do_complex_and_heavy_verify()
        );
        Car { data, base: self }
    }
}

impl Car {
    pub fn into_vehicle(self) -> Vehicle {
        let Self { data, mut base } = self;
        base.maybe_car = Some(data);
        base
    }
}

Or you could have a "pass me your function" interface.

struct Vehicle {
    maybe_car: Option<CarData>,
}

struct Car<'a> {
    data: &'a CarData,
    base: &'a Vehicle,
}

impl Vehicle {
    fn with_car<F>(&mut self, f: F) where F: for<'any> FnOnce(Car<'any>) {
        let data = self.maybe_car.take().unwrap_or_else(
            || do_complex_and_heavy_verify()
        );
        let car = Car { data: &data, base: self };
        f(car);
        self.maybe_car = Some(data);
    }
}