Skip to main content

diskann_utils/
reborrow.rs

1/*
2 * Copyright (c) Microsoft Corporation.
3 * Licensed under the MIT license.
4 */
5
6//! A collection of tools for working with generalized references and scrounging through types.
7
8use sealed::{BoundTo, Sealed};
9
10/// An hybrid combination of reference covariance and borrowing for generalized reference
11/// types.
12/// ```
13/// use diskann_utils::Reborrow;
14/// let mut base = vec![1usize, 3usize];
15///
16/// let borrowed = base.reborrow();
17/// assert_eq!(borrowed[0], 1);
18/// assert_eq!(borrowed[1], 3);
19/// ```
20///
21/// # Notes
22///
23/// The extra hidden generic parameter is an implementation of
24/// <https://sabrinajewson.orgblog/the-better-alternative-to-lifetime-gats/> and allows
25/// [HRTB](https://doc.rust-lang.org/nomicon/hrtb.html) to work properly with shortened
26/// borrows.
27pub trait Reborrow<'this, Lifetime: Sealed = BoundTo<&'this Self>> {
28    type Target;
29
30    /// Borrow `self` into a generalized reference type and reborrow
31    fn reborrow(&'this self) -> Self::Target;
32}
33
34/// An hybrid combination of reference covariance and borrowing for generalized reference
35/// types.
36/// ```ignore
37/// use diskann_utils::ReborrowMut;
38/// let mut base = vec[0, 0];
39/// {
40///     let mut borrowed = base.reborrow_mut();
41///     borrowed[0] = 1;
42///     borrowed[1] = 3;
43/// }
44///
45/// assert_eq!(&*base, &*[1, 3]);
46/// ```
47pub trait ReborrowMut<'this, Lifetime: Sealed = BoundTo<&'this Self>> {
48    type Target;
49
50    /// Mutably borrow `self` into a generalized reference type and reborrow.
51    fn reborrow_mut(&'this mut self) -> Self::Target;
52}
53
54// Custom Impls
55impl<'short, T> Reborrow<'short> for &T
56where
57    T: ?Sized,
58{
59    type Target = &'short T;
60    fn reborrow(&'short self) -> Self::Target {
61        self
62    }
63}
64
65impl<'short, T> ReborrowMut<'short> for &mut T
66where
67    T: ?Sized,
68{
69    type Target = &'short mut T;
70    fn reborrow_mut(&'short mut self) -> Self::Target {
71        self
72    }
73}
74
75impl<'this, T> Reborrow<'this> for Vec<T> {
76    type Target = &'this [T];
77    fn reborrow(&'this self) -> Self::Target {
78        self
79    }
80}
81
82impl<'this, T> ReborrowMut<'this> for Vec<T> {
83    type Target = &'this mut [T];
84    fn reborrow_mut(&'this mut self) -> Self::Target {
85        self
86    }
87}
88
89impl<'this, T> Reborrow<'this> for Box<T>
90where
91    T: ?Sized,
92{
93    type Target = &'this T;
94    fn reborrow(&'this self) -> Self::Target {
95        self
96    }
97}
98
99impl<'this, T> ReborrowMut<'this> for Box<T>
100where
101    T: ?Sized,
102{
103    type Target = &'this mut T;
104    fn reborrow_mut(&'this mut self) -> Self::Target {
105        self
106    }
107}
108
109impl<'short, T> Reborrow<'short> for std::borrow::Cow<'_, T>
110where
111    T: std::borrow::ToOwned + ?Sized,
112{
113    type Target = &'short T;
114    fn reborrow(&'short self) -> Self::Target {
115        self
116    }
117}
118
119impl<'short> Reborrow<'short> for String {
120    type Target = &'short str;
121    fn reborrow(&'short self) -> Self::Target {
122        self
123    }
124}
125
126impl<'short> ReborrowMut<'short> for String {
127    type Target = &'short mut str;
128    fn reborrow_mut(&'short mut self) -> Self::Target {
129        self
130    }
131}
132
133///////////
134// Lower //
135///////////
136
137/// For some problems, neither [`std::ops::Deref`] nor [`Reborrow`] alone are sufficient.
138/// This can occur in cases where
139///
140/// 1. A `?Sized` without lifetimes type is desired for a clean API.
141/// 2. A container cannot implement `Deref` to a target type.
142///
143/// As a concrete example, consider the following:
144/// ```rust
145/// use diskann_utils::Reborrow;
146///
147/// // A type participating in generalized references.
148/// enum ThisOrThat {
149///     This(Vec<f32>),
150///     That(Vec<f64>),
151/// }
152///
153/// enum ThisOrThatView<'a> {
154///     This(&'a [f32]),
155///     That(&'a [f64]),
156/// }
157///
158/// impl<'a> Reborrow<'a> for ThisOrThat {
159///     type Target = ThisOrThatView<'a>;
160///     fn reborrow(&'a self) -> Self::Target {
161///         match self {
162///             Self::This(v) => ThisOrThatView::This(&*v),
163///             Self::That(v) => ThisOrThatView::That(&*v),
164///         }
165///     }
166/// }
167///
168/// // We have a function taking a `?Sized` type.
169/// fn takes_unsized<T: ?Sized>(_: &T) {}
170///
171/// fn calls_unsized<'a, U, T: ?Sized>(x: &'a U) {
172///     // How do I call `takes_unsized`?
173/// }
174/// ```
175/// The question we're trying to answer is: how do we make a trait that allows both
176///
177/// * `calls_unsized::<'a, Vec<f32>, [f32]>`
178/// * `calls_unsized::<'a, ThisOrThat, ThisOrThatView<'a>>`
179///
180/// Observe that `Vec<f32>` can use `Deref` to get to `[f32]`, but no such implementation
181/// is possible for `ThisOrThat`.
182///
183/// # `Lower`
184///
185/// The [`Lower`] trait solves this problem by first lowering `U` to a proxy type that is
186/// then dereferencable to `T`. To solve the above example:
187///
188/// ```rust
189/// # use diskann_utils::Reborrow;
190///
191/// # // A type participating in generalized references.
192/// # enum ThisOrThat {
193/// #     This(Vec<f32>),
194/// #     That(Vec<f64>),
195/// # }
196///
197/// # enum ThisOrThatView<'a> {
198/// #     This(&'a [f32]),
199/// #     That(&'a [f64]),
200/// # }
201///
202/// # impl<'a> Reborrow<'a> for ThisOrThat {
203/// #     type Target = ThisOrThatView<'a>;
204/// #     fn reborrow(&'a self) -> Self::Target {
205/// #         match self {
206/// #             Self::This(v) => ThisOrThatView::This(&*v),
207/// #             Self::That(v) => ThisOrThatView::That(&*v),
208/// #         }
209/// #     }
210/// # }
211///
212/// # // We have a function taking a `?Sized` type.
213/// # fn takes_unsized<T: ?Sized>(_: &T) {}
214///
215/// use diskann_utils::reborrow::Lower;
216///
217/// fn calls_unsized<'a, U, T: ?Sized>(x: &'a U)
218/// where
219///     U: Lower<'a, T>,
220/// {
221///     takes_unsized::<T>(&x.lower())
222/// }
223///
224/// impl<'short> Lower<'short, ThisOrThatView<'short>> for ThisOrThat {
225///     type Proxy = diskann_utils::reborrow::Place<ThisOrThatView<'short>>;
226///     fn lower(&'short self) -> Self::Proxy {
227///         diskann_utils::reborrow::Place(self.reborrow())
228///     }
229/// }
230///
231/// fn with_vec(x: &Vec<f32>) {
232///     calls_unsized::<Vec<f32>, [f32]>(x)
233/// }
234///
235/// fn with_this_or_that<'a>(x: &'a ThisOrThat) {
236///     calls_unsized::<'a, ThisOrThat, ThisOrThatView<'a>>(x)
237/// }
238/// ```
239/// Note the use of [`diskann_utils::reborrow::Place`] to create a type that dereferences to
240/// the contained value.
241pub trait Lower<'short, T: ?Sized, Lifetime: Sealed = BoundTo<&'short Self>> {
242    /// The type of the proxy that dereferences to the target.
243    type Proxy: std::ops::Deref<Target = T>;
244
245    /// Cheaply lower `self` to its proxy type.
246    fn lower(&'short self) -> Self::Proxy;
247}
248
249impl<'a, T> Lower<'a, [T]> for Vec<T> {
250    type Proxy = &'a [T];
251    fn lower(&'a self) -> Self::Proxy {
252        self
253    }
254}
255
256impl<'a, T> Lower<'a, T> for Box<T>
257where
258    T: ?Sized,
259{
260    type Proxy = &'a T;
261    fn lower(&'a self) -> Self::Proxy {
262        self
263    }
264}
265
266impl<'a, T> Lower<'a, T> for std::borrow::Cow<'_, T>
267where
268    T: std::borrow::ToOwned + ?Sized,
269{
270    type Proxy = &'a T;
271    fn lower(&'a self) -> Self::Proxy {
272        self
273    }
274}
275
276/// An async-friendly version of [`Lower`] that further constrains the proxy to be `Send` and
277/// `Sync`.
278///
279/// This trait is automatically implemented for types implementing [`Lower`] whose proxies
280/// are already `Send` and `Sync`.
281///
282/// # Notes
283///
284/// As of time of writing, adding constraints like
285/// ```text
286/// T: Lower<'a, T, Proxy: Send + Sync>
287/// ```
288/// is not sufficient to attach `Send` and `Sync` bounds to the proxy.
289pub trait AsyncLower<'short, T: ?Sized, Lifetime: Sealed = BoundTo<&'short Self>> {
290    type Proxy: std::ops::Deref<Target = T> + Send + Sync;
291    fn async_lower(&'short self) -> Self::Proxy;
292}
293
294impl<'short, T, U> AsyncLower<'short, T> for U
295where
296    T: ?Sized,
297    U: Lower<'short, T, Proxy: Send + Sync>,
298{
299    type Proxy = <Self as Lower<'short, T>>::Proxy;
300    fn async_lower(&'short self) -> Self::Proxy {
301        self.lower()
302    }
303}
304
305////////////
306// Helper //
307////////////
308
309/// A container for types `T` providing an implementation `Deref<Target = T>` as well as
310/// reborrowing functionality mapped to `T as Deref` and `T as DerefMut`.
311#[derive(Debug, Clone, Copy, PartialEq)]
312#[repr(transparent)]
313pub struct Place<T>(pub T);
314
315impl<T> std::ops::Deref for Place<T> {
316    type Target = T;
317    fn deref(&self) -> &T {
318        &self.0
319    }
320}
321
322impl<T> std::ops::DerefMut for Place<T> {
323    fn deref_mut(&mut self) -> &mut T {
324        &mut self.0
325    }
326}
327
328impl<'this, T> Reborrow<'this> for Place<T>
329where
330    T: std::ops::Deref,
331{
332    type Target = &'this T::Target;
333    fn reborrow(&'this self) -> Self::Target {
334        self
335    }
336}
337
338impl<'this, T> ReborrowMut<'this> for Place<T>
339where
340    T: std::ops::DerefMut,
341{
342    type Target = &'this mut T::Target;
343    fn reborrow_mut(&'this mut self) -> Self::Target {
344        self
345    }
346}
347
348/// A container that reborrows by cloning the contained value.
349///
350/// Note that [`ReborrowMut`] is not implemented for this type.
351#[derive(Debug, Clone, Copy, PartialEq)]
352#[repr(transparent)]
353pub struct Cloned<T>(pub T)
354where
355    T: Clone;
356
357impl<T> std::ops::Deref for Cloned<T>
358where
359    T: Clone,
360{
361    type Target = T;
362    fn deref(&self) -> &Self::Target {
363        &self.0
364    }
365}
366
367impl<T> std::ops::DerefMut for Cloned<T>
368where
369    T: Clone,
370{
371    fn deref_mut(&mut self) -> &mut Self::Target {
372        &mut self.0
373    }
374}
375
376impl<'this, T> Reborrow<'this> for Cloned<T>
377where
378    T: Clone,
379{
380    type Target = Self;
381
382    fn reborrow(&'this self) -> Self::Target {
383        self.clone()
384    }
385}
386
387/// A container that reborrows by copying the contained value.
388///
389/// Note that [`ReborrowMut`] is not implemented for this type.
390#[derive(Debug, Clone, Copy, PartialEq)]
391#[repr(transparent)]
392pub struct Copied<T>(pub T)
393where
394    T: Copy;
395
396impl<T> std::ops::Deref for Copied<T>
397where
398    T: Copy,
399{
400    type Target = T;
401    fn deref(&self) -> &Self::Target {
402        &self.0
403    }
404}
405
406impl<T> std::ops::DerefMut for Copied<T>
407where
408    T: Copy,
409{
410    fn deref_mut(&mut self) -> &mut Self::Target {
411        &mut self.0
412    }
413}
414
415impl<'this, T> Reborrow<'this> for Copied<T>
416where
417    T: Copy,
418{
419    type Target = Self;
420
421    fn reborrow(&'this self) -> Self::Target {
422        *self
423    }
424}
425
426macro_rules! trivial_reborrow {
427    ($T:ty) => {
428        impl<'a> Reborrow<'a> for $T {
429            type Target = Self;
430
431            fn reborrow(&'a self) -> Self {
432                *self
433            }
434        }
435    };
436    ($($T:ty),* $(,)?) => {
437        $(trivial_reborrow!($T);)*
438    }
439}
440
441trivial_reborrow!(half::f16, f32, f64, u8, u16, u32, u64, i8, i16, i32, i64);
442
443/// Helper traits for the [HRTB]() trick.
444mod sealed {
445    pub trait Sealed: Sized {}
446    pub struct BoundTo<T>(T);
447    impl<T> Sealed for BoundTo<T> {}
448}
449
450///////////
451// Tests //
452///////////
453
454#[cfg(test)]
455mod tests {
456    use super::*;
457
458    fn test_hrtb_reborrow<T>(_x: T)
459    where
460        T: for<'a> Reborrow<'a>,
461    {
462    }
463
464    fn test_hrtb_reborrow_mut<T>(_x: T)
465    where
466        T: for<'a> ReborrowMut<'a>,
467    {
468    }
469
470    fn test_reborrow_constrained<T>(x: T) -> String
471    where
472        T: for<'a> Reborrow<'a, Target: std::fmt::Debug>,
473    {
474        format!("{:?}", x.reborrow())
475    }
476
477    #[test]
478    fn hrbt_reborrow() {
479        let x: &[usize] = &[10];
480        test_hrtb_reborrow(x);
481    }
482
483    #[test]
484    fn hrbt_reborrow_mut() {
485        let x: &mut [usize] = &mut [10];
486        test_hrtb_reborrow_mut(x);
487    }
488
489    #[test]
490    fn reborrow_constrained() {
491        let x: &[usize] = &[10];
492        let s = test_reborrow_constrained(x);
493        assert_eq!(s, "[10]");
494    }
495
496    ////////////////////////
497    // Reborrow built-ins //
498    ////////////////////////
499
500    #[test]
501    fn test_slice() {
502        let x: &[usize] = &[1, 2, 3];
503        let ptr = x.as_ptr();
504        let len = x.len();
505
506        let y: &[usize] = x.reborrow();
507        assert_eq!(ptr, y.as_ptr());
508        assert_eq!(len, y.len());
509    }
510
511    #[test]
512    fn test_mut_slice() {
513        let mut x: &mut [usize] = &mut [0, 0, 0];
514        let ptr = x.as_ptr();
515        let len = x.len();
516
517        let y: &mut [usize] = x.reborrow_mut();
518        assert_eq!(ptr, y.as_ptr());
519        assert_eq!(len, y.len());
520        y[0] = 1;
521        y[1] = 2;
522        y[2] = 3;
523
524        assert_eq!(x, [1, 2, 3]);
525    }
526
527    #[test]
528    fn test_vec() {
529        let x: Vec<usize> = vec![1, 2, 3];
530        let ptr = x.as_ptr();
531        let len = x.len();
532
533        let y: &[usize] = x.reborrow();
534        assert_eq!(ptr, y.as_ptr());
535        assert_eq!(len, y.len());
536    }
537
538    #[test]
539    fn test_vec_mut() {
540        let mut x: Vec<usize> = vec![0, 0, 0];
541        let ptr = x.as_ptr();
542        let len = x.len();
543
544        let y: &mut [usize] = x.reborrow_mut();
545        assert_eq!(ptr, y.as_ptr());
546        assert_eq!(len, y.len());
547        y[0] = 1;
548        y[1] = 2;
549        y[2] = 3;
550
551        assert_eq!(x, [1, 2, 3]);
552    }
553
554    #[test]
555    fn test_box() {
556        let x: Box<[usize]> = Box::new([1, 2, 3]);
557        let ptr = x.as_ptr();
558        let len = x.len();
559
560        let y: &[usize] = x.reborrow();
561        assert_eq!(ptr, y.as_ptr());
562        assert_eq!(len, y.len());
563    }
564
565    #[test]
566    fn test_box_mut() {
567        let mut x: Box<[usize]> = Box::new([0, 0, 0]);
568        let ptr = x.as_ptr();
569        let len = x.len();
570
571        let y: &mut [usize] = x.reborrow_mut();
572        assert_eq!(ptr, y.as_ptr());
573        assert_eq!(len, y.len());
574        y[0] = 1;
575        y[1] = 2;
576        y[2] = 3;
577
578        assert_eq!(&*x, [1, 2, 3]);
579    }
580
581    #[test]
582    fn test_cow() {
583        let x = &[1, 2, 3];
584        let ptr = x.as_ptr();
585        let len = x.len();
586        let cow = std::borrow::Cow::<[usize]>::Borrowed(x);
587
588        let y: &[usize] = cow.reborrow();
589        assert_eq!(ptr, y.as_ptr());
590        assert_eq!(len, y.len());
591
592        let cow = cow.into_owned();
593        let ptr = cow.as_ptr();
594        let len = cow.len();
595
596        let y: &[usize] = cow.reborrow();
597        assert_eq!(ptr, y.as_ptr());
598        assert_eq!(len, y.len());
599    }
600
601    #[test]
602    fn test_string() {
603        let mut x = String::from("hello world");
604        let ptr = x.as_ptr();
605        let len = x.len();
606
607        let y: &str = x.reborrow();
608        assert_eq!(y, x);
609        assert_eq!(ptr, y.as_ptr());
610        assert_eq!(len, y.len());
611
612        let y: &mut str = x.reborrow_mut();
613        assert_eq!(ptr, y.as_ptr());
614        assert_eq!(len, y.len());
615        y.make_ascii_uppercase();
616
617        assert_eq!(x, "HELLO WORLD");
618    }
619
620    /////////////////////
621    // Lower Built-Ins //
622    /////////////////////
623
624    #[test]
625    fn test_lower_vec() {
626        let v = vec![1, 2, 3];
627        let ptr = v.as_ptr();
628        let slice: &[usize] = v.lower();
629        assert_eq!(ptr, slice.as_ptr());
630        assert_eq!(slice, [1, 2, 3]);
631
632        let slice: &[usize] = v.async_lower();
633        assert_eq!(ptr, slice.as_ptr());
634        assert_eq!(slice, [1, 2, 3]);
635    }
636
637    #[test]
638    fn test_lower_box() {
639        let v: Box<[usize]> = Box::new([1, 2, 3]);
640        let ptr = v.as_ptr();
641        let slice: &[usize] = v.lower();
642        assert_eq!(ptr, slice.as_ptr());
643        assert_eq!(slice, [1, 2, 3]);
644
645        let slice: &[usize] = v.async_lower();
646        assert_eq!(ptr, slice.as_ptr());
647        assert_eq!(slice, [1, 2, 3]);
648    }
649
650    #[test]
651    fn test_lower_cow() {
652        let x = &[1, 2, 3];
653        let ptr = x.as_ptr();
654        let cow = std::borrow::Cow::<[usize]>::Borrowed(x);
655
656        let y: &[usize] = cow.lower();
657        assert_eq!(ptr, y.as_ptr());
658        assert_eq!(y, [1, 2, 3]);
659
660        let cow = cow.into_owned();
661        let ptr = cow.as_ptr();
662
663        let y: &[usize] = cow.lower();
664        assert_eq!(ptr, y.as_ptr());
665        assert_eq!(y, [1, 2, 3]);
666
667        let y: &[usize] = cow.async_lower();
668        assert_eq!(ptr, y.as_ptr());
669        assert_eq!(y, [1, 2, 3]);
670    }
671
672    // A type participating in generalized references.
673    enum ThisOrThat {
674        This(Vec<f32>),
675        That(Vec<f64>),
676    }
677
678    #[allow(dead_code)]
679    enum ThisOrThatView<'a> {
680        This(&'a [f32]),
681        That(&'a [f64]),
682    }
683
684    impl<'a> Reborrow<'a> for ThisOrThat {
685        type Target = ThisOrThatView<'a>;
686        fn reborrow(&'a self) -> Self::Target {
687            match self {
688                Self::This(v) => ThisOrThatView::This(v),
689                Self::That(v) => ThisOrThatView::That(v),
690            }
691        }
692    }
693
694    // We have a function taking a `?Sized` type.
695    fn takes_unsized<T: ?Sized>(_x: &T) -> bool {
696        true
697    }
698
699    fn calls_unsized<'a, U, T: ?Sized>(x: &'a U) -> bool
700    where
701        U: Lower<'a, T>,
702    {
703        takes_unsized::<T>(&x.lower())
704    }
705
706    impl<'short> Lower<'short, ThisOrThatView<'short>> for ThisOrThat {
707        type Proxy = Place<ThisOrThatView<'short>>;
708        fn lower(&'short self) -> Self::Proxy {
709            Place(self.reborrow())
710        }
711    }
712
713    fn with_vec(x: &Vec<f32>) -> bool {
714        calls_unsized::<Vec<f32>, [f32]>(x)
715    }
716
717    fn with_this_or_that<'a>(x: &'a ThisOrThat) -> bool {
718        calls_unsized::<'a, ThisOrThat, ThisOrThatView<'a>>(x)
719    }
720
721    #[test]
722    fn test_lower_example() {
723        assert!(with_vec(&vec![1.0, 2.0, 3.0]));
724        assert!(with_this_or_that(&ThisOrThat::This(vec![2.0, 3.0, 4.0])));
725        assert!(with_this_or_that(&ThisOrThat::That(vec![2.0, 3.0, 4.0])));
726    }
727
728    ///////////
729    // Place //
730    ///////////
731
732    #[test]
733    fn test_place() {
734        let mut x: Place<Box<[usize]>> = Place(Box::new([0, 0, 0]));
735        // DerefMut through `Box`.
736        x[0] = 1;
737        x[1] = 2;
738        x[2] = 3;
739
740        assert_eq!(&**x, [1, 2, 3]);
741        assert_eq!(x.reborrow(), [1, 2, 3]);
742
743        *x = Box::new([2, 3, 4]);
744        assert_eq!(&**x, [2, 3, 4]);
745        assert_eq!(x.reborrow(), [2, 3, 4]);
746
747        let y = x.reborrow_mut();
748        y[0] = 10;
749        y[1] = 20;
750        y[2] = 30;
751        assert_eq!(&**x, [10, 20, 30]);
752        assert_eq!(x.reborrow(), [10, 20, 30]);
753    }
754
755    /////////////
756    // Helpers //
757    /////////////
758
759    #[test]
760    fn test_cloned() {
761        let mut x = Cloned(10);
762        assert_eq!(*x, 10);
763
764        let y: Cloned<usize> = x.reborrow();
765        assert_eq!(x, y);
766
767        // Test derive copy;
768        let z = x;
769        assert_eq!(*z, 10);
770
771        // DerefMut
772        *x = 50;
773        assert_eq!(*x, 50);
774        assert_ne!(x, y);
775    }
776
777    #[test]
778    fn test_copied() {
779        let mut x = Copied(10);
780        assert_eq!(*x, 10);
781
782        let y: Copied<usize> = x.reborrow();
783        assert_eq!(x, y);
784
785        // Test derive copy;
786        let z = x;
787        assert_eq!(*z, 10);
788
789        // DerefMut
790        *x = 50;
791        assert_eq!(*x, 50);
792        assert_ne!(x, y);
793    }
794
795    //////////////////////
796    // Trivial Reborrow //
797    //////////////////////
798
799    fn reborrow_to_self<T>(x: T) -> T
800    where
801        for<'a> T: Reborrow<'a, Target = T>,
802    {
803        x.reborrow()
804    }
805
806    #[test]
807    fn trivial_reborrows() {
808        assert_eq!(
809            reborrow_to_self::<half::f16>(Default::default()),
810            Default::default()
811        );
812        assert_eq!(reborrow_to_self::<f32>(1.0f32), 1.0);
813        assert_eq!(reborrow_to_self::<f64>(1.0f64), 1.0);
814
815        assert_eq!(reborrow_to_self::<i8>(1), 1);
816        assert_eq!(reborrow_to_self::<i16>(1), 1);
817        assert_eq!(reborrow_to_self::<i32>(1), 1);
818        assert_eq!(reborrow_to_self::<i64>(1), 1);
819
820        assert_eq!(reborrow_to_self::<u8>(1), 1);
821        assert_eq!(reborrow_to_self::<u16>(1), 1);
822        assert_eq!(reborrow_to_self::<u32>(1), 1);
823        assert_eq!(reborrow_to_self::<u64>(1), 1);
824    }
825}