Struct deferred_reference::Deferred[][src]

#[repr(transparent)]pub struct Deferred<T> where
    T: Reference
{ /* fields omitted */ }

A smart pointer which holds a “deferred reference” to an instance of type T: ?Sized. It has all the properties of a normal reference (&T or &mut T), except that it does not hold an actual reference. This makes it possible pass around multiple deferred references in unsafe code, without triggering undefined behavior due to existence of aliased mutable references. Deferred aims to make it easier to reason about the validity and lifetime of pointers during the act of dereferencing.

Invariant

Deferred upholds the same guarantees as its referenceable counter-parts &T and &mut T (except that it doesn’t occupy an actual reference!), it is possible to always dereference it:

  • The address that Deferred points to is guaranteed to be properly aligned.
  • Deferred is guaranteed to be non-dangling.
  • Deferred is guaranteed to be non-null.
  • Deferred is guaranteed to dereference to the same (stack-allocated) object.
  • The memory that Deferred points to is guaranteed to be properly initialized.
  • Deferred is guaranteed to be valid for the duration of its lifetime.

For mutable pointers, Deferred<&mut T> guarantees that no mutable reference(s) existed to (any part of) the T instance at the time the Deferred was constructed. After a mutable Deferred<&mut T> is created, mutable references may be constructed from it (safely or unsafely), but the Rust aliasing rules must always be respected, meaning no two live mutable references may point to overlapping regions in memory, ever.

Safety

Even though it is possible to work with Deferred from purely safe Rust, it also offers additional functionality in unsafe code and then the programmer must take special care when dereferencing the Deferred or its pointers in unsafe code regarding the usual Rust rules:

  • Don’t create a mutable reference &mut T to regions of the memory which already hold an immutable reference &T or a mutable reference &mut T. The usual Rust aliasing rules still apply, even in unsafe code!
  • Don’t create any reference, &T or &mut T, to regions of the memory which could be modified from other threads or processes.
  • Don’t create any mutable reference &mut T to regions of the memory which could be aliased through a &T or &mut T from other threads or processes.
  • Creating immutable aliases &T to regions of the memory is fine as long as there are only readers for the same part of the slice, even if it is read from other threads or processes.

Implementations

impl<'a, T: ?Sized> Deferred<&'a T>[src]

Constructors for deferred immutable references

There exist several ways to construct a deferred immutable reference Deferred<&T>, listed here in order of safety (lower in the list means it’s more unsafe).

  1. Through the Deferred::new method.
  2. Through the From/Into traits implemented for Deferred<&T>.
  3. Through the Defer::defer method on types that implement the Defer trait.
  4. Through the unsafe Deferred::from_raw method.
  5. Through the extremely unsafe defer macro (not recommended).

pub fn new(reference: &'a T) -> Self[src]

Construct a new deferred immutable reference from an existing immutable reference.

use deferred_reference::Deferred;
let x = [1, 2, 3];
let deferred = Deferred::new(&x);
assert_eq!(2, deferred[1]);

pub unsafe fn from_raw(ptr: *const T) -> Self[src]

Construct a new deferred immutable reference to an instance of T: ?Sized from a raw pointer. This method is unsafe. For a safe alternative, use Deferred::from(&T) instead. If you don’t have access to a reference or don’t want to create one, then this method (Deferred::from_raw) is the method that you could use instead. Alternatively, another safe method is to call the Defer::defer method on types that implement the Defer trait.

Safety

The caller must uphold the invariant of Deferred, which implies guaranteeing largely the same safety guarantees as for regular immutable references. Most importantly this means that the pointer must be derefenceable and may not contain any part of memory which is left uninitialized. Referencing uninitialized memory of any type is always instant undefined behavior (see the nomicon at https://doc.rust-lang.org/nomicon/uninitialized.html for more details on this fact). The caller must also ensure that the pointer remains valid for as long as the returned Deferred exists. If the pointers refers to a shared memory (mapped) region which may be modified somehow, then it is also the caller’s reponsibility never to call safe methods such as <Deferred as Deref>::deref. This would alias the entire memory region and is only safe if there are no writers at the same time.

Caveat

The lifetime for the returned Deferred is inferred from its usage. To prevent accidental misuse, it’s suggested to tie the lifetime to whichever source lifetime is safe in the context, such as by providing a helper function taking the lifetime of a host value, or by explicit annotation.

use deferred_reference::Deferred;
pub trait MemoryMappedBuffer {
    fn as_ptr(&self) -> *const u8;
    fn len(&self) -> usize;
}
fn defer<'a, T>(buffer: &'a T) -> Deferred<&'a [u8]>
where
    T: MemoryMappedBuffer
{
    let slice_ptr = core::ptr::slice_from_raw_parts(buffer.as_ptr(), buffer.len());
    unsafe { Deferred::from_raw(slice_ptr) }
}

Example

use deferred_reference::Deferred;
let buffer = [0u8; 1024];
// SAFETY: `buffer` is not moved or mutably aliased after this.
let deferred = unsafe { Deferred::from_raw(core::ptr::addr_of!(buffer)) };

impl<'a, T: ?Sized> Deferred<&'a mut T>[src]

Constructors for deferred mutable references

There exist several ways to construct a deferred mutable reference Deferred<&mut T>, listed here in order of safety (lower in the list means it’s more unsafe).

  1. Through the Deferred::new_mut method.
  2. Through the From/Into traits implemented for Deferred<&mut T>.
  3. Through the unsafe DeferMut::defer_mut method on types that implement the DeferMut trait.
  4. Through the unsafe Deferred::from_raw_mut method.
  5. Through the extremely unsafe defer_mut macro (not recommended).

pub fn new_mut(reference: &'a mut T) -> Self[src]

Construct a new deferred mutable reference from an existing mutable reference.

use deferred_reference::Deferred;
let mut x = [1, 2, 3];
let mut deferred = Deferred::new_mut(&mut x);
assert_eq!(&mut 2, &mut deferred[1]);

pub unsafe fn from_raw_mut(ptr: *mut T) -> Deferred<&'a mut T>[src]

Construct a new deferred mutable reference to an instance of T.

Safety

The caller must uphold the invariant of Deferred. Most importantly this means that the pointer must be derefenceable and may not contain any part of memory which is left uninitialized. Referencing uninitialized memory of any type is always instant undefined behavior (see the nomicon at https://doc.rust-lang.org/nomicon/uninitialized.html for more details on this fact). On top of that, the caller must ensure that the pointer remains valid for as long as the returned Deferred exists and that no references to the instance exist when the Deferred is constructed. If the Deferred refers to a shared memory (mapped) region which may be modified somehow (e.g. by other threads or processes), then it is also the caller’s reponsibility never to call the safe methods <Deferred as Deref>::deref or <Deferred as DerefMut>::deref_mut. This would alias the entire memory region and is only safe when there are no other writers and readers, respectively.

Caveat

The lifetime for the returned Deferred is inferred from its usage. To prevent accidental misuse, it’s suggested to tie the lifetime to whichever source lifetime is safe in the context, such as by providing a helper function taking the lifetime of a host value, or by explicit annotation.

use deferred_reference::Deferred;
/// SAFETY: `Buffer` may only be implemented on valid smart-pointers which don't own
/// SAFETY: the memory. The smart pointer must also point to fully initialized memory.
pub unsafe trait Buffer {
    fn as_ptr(&self) -> *mut u8;
    fn len(&self) -> usize;
}
/// The lifetime of the returned [Deferred] is bound to the lifetime of the
/// mutable borrow of smart pointer `T` through the explicit lifetime 'a.
fn defer_mut<'a, T>(buffer: &'a mut T) -> Deferred<&'a mut [u8]>
where
    T: Buffer
{
    let slice_ptr = core::ptr::slice_from_raw_parts_mut(buffer.as_ptr(), buffer.len());
    // SAFETY: this is safe because `Deferred` occupies the only mutable reference
    // SAFETY: to the smart pointer `T` for the duration of lifetime 'a, which means
    // SAFETY: no other callers can safely obtain a mutable reference at the same time.
    unsafe { Deferred::from_raw_mut(slice_ptr) }
}

The documentation of DeferMut contains some additional examples of how to properly call Deferred::from_raw_mut.

impl<T> Deferred<T> where
    T: Reference
[src]

pub fn as_ptr(&self) -> *const T::Target[src]

Obtains an immutable pointer to where the deferred reference points. This pointer can be a thin pointer if T is sized or a fat pointer otherwise.

pub fn unsize<U>(self) -> Deferred<U> where
    U: Reference,
    NonNull<T::Target>: CoerceUnsized<NonNull<U::Target>>, 
[src]

Unsizes the deferred reference. This method is experimental.

Example

use deferred_reference::{Defer, DeferMut, Deferred};
use core::cell::UnsafeCell;
let mut buffer = UnsafeCell::new([0u8; 1024]);
let deferred_array /* : Deferred<&[u8; 1024]> */ = buffer.defer();
let deferred_slice: Deferred<&[u8]> = deferred_array.unsize(); // needs an explicit type
let deferred_array_mut /* : Deferred<&mut [u8; 1024]> */ = unsafe { buffer.defer_mut() };
let deferred_slice_mut: Deferred<&mut [u8]> = deferred_array_mut.unsize();

Unstable

This method requires the unstable Cargo.toml feature unstable or coerce_unsized to be enabled. This method may become stable once the coerce_unsized feature lands in stable Rust, see https://github.com/rust-lang/rust/issues/27732. For a stable alternative, you may also use use the From/Into traits which are implemented on Deferred for converting deferred arrays to deferred slices.

impl<'a, T: ?Sized> Deferred<&'a mut T>[src]

pub fn as_mut_ptr(&self) -> *mut T[src]

Obtains an mutable pointer to where the deferred reference points. This pointer can be a thin pointer if T is sized or a fat pointer otherwise.

pub unsafe fn clone_unchecked(&self) -> Self[src]

Make a copy of this mutable Deferred<&'a mut T>. The copy will have the same lifetime as 'a.

Safety

This method can be very unsafe. Cloning a mutable deferred reference will let you safely dereference it mutably afterwards (e.g. through <Deferred<&mut T> as DerefMut>::deref_mut) from several distinct places simultaneously and this could lead to aliased mutable references which is then instant undefined behavior. That is why this function is marked as unsafe. Cloning a Deferred<&mut T> is not undefined behavior, because this is a smart pointer and not an actual live reference. Be very careful not to accidentally create mutable aliased references through dereferencing any Deferred<&mut T> after calling Deferred::clone_unchecked on it!!! Calling <Deferred as Clone>::clone on immutable deferred references (i.e. Deferred<&T>) is entirely safe (and all Deferred<&T> also implement the Copy trait).

pub fn into_ref(self) -> Deferred<&'a T>[src]

Convert this deferred mutable reference into a deferred immutable reference.

Example

use deferred_reference::{DeferMut, Deferred};
use core::cell::UnsafeCell;
let buffer = UnsafeCell::new([0u8; 1024]);
// SAFETY: this is safe, because this is the only deferred reference we create:
let deferred_mut: Deferred<&mut [u8; 1024]> = unsafe { buffer.defer_mut() };
// which we then convert into a deferred immutable reference:
let deferred: Deferred<&[u8; 1024]> = deferred_mut.into_ref();

impl<T> Deferred<T> where
    T: Reference,
    T::Target: SliceLike
[src]

Methods only available for deferred references to slices and arrays

Deferred overrides some of the standard methods for arrays and slices, in order to allow for deferred access to disjoint indices. The idea is that if you only need a reference to a specific element or subslice, then it is not necessary to create a reference to the entire array or slice. The overriden methods are listed below. In addition to the overriden methods listed below, Deferred also overrides the Index and IndexMut traits on slices and arrays. This allows for direct access to disjoint subslices, without triggering undefined behavior, using the syntactic sugar of Rust:

use deferred_reference::Deferred;
let mut buffer = [0u8; 300];
let mut a = Deferred::from(&mut buffer); // a mutable deferred reference
let b = unsafe { a.clone_unchecked().into_ref() }; // immutable deferred reference
let mut c = unsafe { a.clone_unchecked() }; // another mutable deferred reference
let mut_ref1 = &mut a[0..100];
assert_eq!(&[0u8; 100], &b[100..200]);
c[200..].copy_from_slice(&[1u8; 100]);
assert_eq!(&mut [1u8; 100], &mut c[200..]);
assert_eq!(&mut [0u8; 100], mut_ref1);

The above example also works on stable Rust, because buffer is an array. However, for slices this will not work on stable Rust, at least not until the slice_ptr_len feature is stabilized. On nightly Rust, this is already possible with slices, too. In order to work with slices on stable Rust (or on nightly Rust without the unstable features disabled), you will need to insert an explicit call to Deref::deref or DerefMut::deref_mut in order to reach the slice, which will create a reference to the entire slice (without this extra step, you will get a panic). This is made explicit like this to avoid ambiguity when a method resolves to a subslice or the entire slice. Here is an example of how to use Deferred on stable Rust with slices, under the condition that indexing operations are disjoint in lifetime (instead of disjoint w.r.t. the indices):

use deferred_reference::Deferred;
use core::ops::{Deref, DerefMut};
let mut buffer = [0u8; 300];
let mut a: Deferred<&mut [u8]> = Deferred::from(&mut buffer).into(); // a slice
let b = unsafe { a.clone_unchecked().into_ref() }; // immutable deferred reference
let mut c = unsafe { a.clone_unchecked() }; // another mutable deferred reference;
let mut_ref1 = &mut a.deref_mut()[0..100]; // accesses `a` for lifetime 'a
assert_eq!(&mut [0u8; 100], &mut mut_ref1[0..100]); // lifetime 'a ends after this statement
assert_eq!(&[0u8; 100], &b.deref()[100..200]); // accesses `b` for short-lived lifetime 'b
c.deref_mut()[200..].copy_from_slice(&[1u8; 100]); // accesses `c` for short-lived lifetime 'c
assert_eq!(&mut [1u8; 100], &mut c.deref_mut()[200..]); // accesses `c` for lifetime 'd

pub fn len(&self) -> usize[src]

Obtains the length of the array or slice that this Deferred points to, without creating an intermediate reference to the array or slice.

Example

use core::cell::UnsafeCell;
use deferred_reference::{Defer, Deferred};
let buffer = UnsafeCell::new([0u8; 1024]);
let deferred: Deferred<_> = buffer.defer();
assert_eq!(1024, deferred.len());

Panics

As of yet, the length of slices (which are a dynamically sized type, unlike fixed size arrays) can only be accessed when the unstable Cargo.toml feature slice_ptr_len or unstable is enabled. If you call this method on a deferred slice without one of these features enabled, then this method will panic. This method will become panic-less for slices when the slice_ptr_len feature lands in Rust stable, see https://github.com/rust-lang/rust/issues/71146. It is still possible to access the length of a fixed sized array [T; N] without dereferencing the array in stable Rust (meaning, even without the use of unstable features and without risk of panics).

pub fn get<I>(&self, index: I) -> Option<&I::Output> where
    I: SlicePointerIndex<T::Target>, 
[src]

Returns a reference to an element or subslice depending on the type of index, without creating a reference to the other elements in the slice.

  • If given a position, returns a reference to the element at that position or None if out of bounds.
  • If given a range, returns the subslice corresponding to that range, or None if out of bounds.

Examples

use deferred_reference::Deferred;
let v = Deferred::from(&[10, 40, 30]);
assert_eq!(Some(&40), v.get(1));
assert_eq!(Some(&[10, 40][..]), v.get(0..2));
assert_eq!(None, v.get(3));
assert_eq!(None, v.get(0..4));

pub unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output where
    I: SlicePointerIndex<T::Target>, 
[src]

Returns a reference to an element or subslice, without doing bounds checking and without creating a reference to the other elements in the slice.

For a safe alternative see get.

Safety

Calling this method with an out-of-bounds index is undefined behavior even if the resulting reference is not used.

Examples

use deferred_reference::Deferred;
let x = Deferred::from(&[1, 2, 4]);

unsafe {
    assert_eq!(x.get_unchecked(1), &2);
}

pub unsafe fn split_at_unchecked(
    &self,
    mid: usize
) -> (Deferred<&[<T::Target as SliceLike>::Element]>, Deferred<&[<T::Target as SliceLike>::Element]>)
[src]

Divides one deferred slice into two deferred slices at an index, without doing bounds checking and without creating any intermediate references.

The first will contain all indices from [0, mid) (excluding the index mid itself) and the second will contain all indices from [mid, len) (excluding the index len itself).

For a safe alternative see split_at.

Safety

Calling this method with an out-of-bounds index is undefined behavior even if the resulting reference is not used. The caller has to ensure that 0 <= mid <= self.len().

Examples

use deferred_reference::Deferred;
let v = [1, 2, 3, 4, 5, 6];
let deferred = Deferred::new(&v);

unsafe {
   let (left, right) = deferred.split_at_unchecked(0);
   assert_eq!(*left, []);
   assert_eq!(*right, [1, 2, 3, 4, 5, 6]);
}

unsafe {
    let (left, right) = deferred.split_at_unchecked(2);
    assert_eq!(*left, [1, 2]);
    assert_eq!(*right, [3, 4, 5, 6]);
}

unsafe {
    let (left, right) = deferred.split_at_unchecked(6);
    assert_eq!(*left, [1, 2, 3, 4, 5, 6]);
    assert_eq!(*right, []);
}

pub fn split_at(
    &self,
    mid: usize
) -> (Deferred<&[<T::Target as SliceLike>::Element]>, Deferred<&[<T::Target as SliceLike>::Element]>)
[src]

Divides one deferred slice into two deferred slices at an index, without creating any intermediate references.

The first will contain all indices from [0, mid) (excluding the index mid itself) and the second will contain all indices from [mid, len) (excluding the index len itself).

Panics

Panics if mid > len.

Examples

use deferred_reference::Deferred;
let v = [1, 2, 3, 4, 5, 6];
let deferred = Deferred::new(&v);
{
   let (left, right) = deferred.split_at(0);
   assert_eq!(*left, []);
   assert_eq!(*right, [1, 2, 3, 4, 5, 6]);
}

{
    let (left, right) = deferred.split_at(2);
    assert_eq!(*left, [1, 2]);
    assert_eq!(*right, [3, 4, 5, 6]);
}

{
    let (left, right) = deferred.split_at(6);
    assert_eq!(*left, [1, 2, 3, 4, 5, 6]);
    assert_eq!(*right, []);
}

{
    // this method overrides the `<[T]>::split_at` method from the core library
    // if you rather have actual slices than deferred slices, insert a `deref` like so:
    use core::ops::Deref;
    let (left, right) /* : (&[_], &[_]) */ = deferred.deref().split_at(2);
    assert_eq!(left, [1, 2]);
    assert_eq!(right, [3, 4, 5, 6]);
}

impl<T: ?Sized> Deferred<&mut T> where
    T: SliceLike
[src]

pub fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output> where
    I: SlicePointerIndex<T>, 
[src]

Returns a mutable reference to an element or subslice depending on the type of index (see get) or None if the index is out of bounds. This method will not create a reference to the other elements in the slice.

Examples

use deferred_reference::Deferred;
use core::ops::Deref;
let mut x = [0, 1, 2];
let mut x = Deferred::from(&mut x);

if let Some(elem) = x.get_mut(1) {
    *elem = 42;
}
assert_eq!(x.deref(), &[0, 42, 2]);

pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output where
    I: SlicePointerIndex<T>, 
[src]

Returns a mutable reference to an element or subslice, without doing bounds checking and without creating a reference to the other elements in the slice.

For a safe alternative see get_mut.

Safety

Calling this method with an out-of-bounds index is undefined behavior even if the resulting reference is not used.

Examples

use deferred_reference::Deferred;
use core::ops::Deref;
let mut x = [1, 2, 4];
let mut x = Deferred::from(&mut x);

unsafe {
    let elem = x.get_unchecked_mut(1);
    *elem = 13;
}
assert_eq!(x.deref(), &[1, 13, 4]);

pub unsafe fn split_at_mut_unchecked(
    &mut self,
    mid: usize
) -> (Deferred<&mut [T::Element]>, Deferred<&mut [T::Element]>)
[src]

Divides one deferred mutable slice into two deferred mutable slice at an index, without doing bounds checking and without creating any intermediate references.

The first will contain all indices from [0, mid) (excluding the index mid itself) and the second will contain all indices from [mid, len) (excluding the index len itself).

For a safe alternative see split_at_mut.

Safety

Calling this method with an out-of-bounds index is undefined behavior even if the resulting reference is not used. The caller has to ensure that 0 <= mid <= self.len().

Examples

use deferred_reference::Deferred;
let mut v = [1, 0, 3, 0, 5, 6];
let mut deferred = Deferred::new_mut(&mut v);
// scoped to restrict the lifetime of the borrows
unsafe {
    let (mut left, mut right) = deferred.split_at_mut_unchecked(2);
    assert_eq!(*left, [1, 0]);
    assert_eq!(*right, [3, 0, 5, 6]);
    left[1] = 2;
    right[1] = 4;
}
assert_eq!(*deferred, [1, 2, 3, 4, 5, 6]);

pub fn split_at_mut(
    &mut self,
    mid: usize
) -> (Deferred<&mut [T::Element]>, Deferred<&mut [T::Element]>)
[src]

Divides one mutable slice into two at an index.

The first will contain all indices from [0, mid) (excluding the index mid itself) and the second will contain all indices from [mid, len) (excluding the index len itself).

Panics

Panics if mid > len.

Examples

use deferred_reference::Deferred;
let mut v = [1, 0, 3, 0, 5, 6];
let mut deferred = Deferred::new_mut(&mut v);
let (mut left, mut right) = deferred.split_at_mut(2);
assert_eq!(*left, [1, 0]);
assert_eq!(*right, [3, 0, 5, 6]);
left[1] = 2;
right[1] = 4;
assert_eq!(*deferred, [1, 2, 3, 4, 5, 6]);
// this method overrides the `<[T]>::split_at_mut` method from the core library
// if you rather have actual slices than deferred slices, insert a `deref_mut` like so:
use core::ops::DerefMut;
let (left, right) /* : (&mut [_], &mut [_]) */ = deferred.deref_mut().split_at(2);
assert_eq!(*left, [1, 2]);
assert_eq!(*right, [3, 4, 5, 6]);

Trait Implementations

impl<T: Clone + Copy + Reference> Clone for Deferred<T>[src]

impl<T: Copy + Reference> Copy for Deferred<T>[src]

impl<T: Reference> Defer for Deferred<T>[src]

type Target = T::Target

The type that the deferred reference points to.

impl<T: ?Sized> DeferMut for Deferred<&mut T>[src]

impl<T: Reference> Deref for Deferred<T>[src]

type Target = T::Target

The resulting type after dereferencing.

impl<T: ?Sized> DerefMut for Deferred<&mut T>[src]

impl<'a, T: ?Sized> From<&'a T> for Deferred<&'a T>[src]

impl<'a, T: ?Sized> From<&'a mut T> for Deferred<&'a mut T>[src]

impl<'a, T, const N: usize> From<Deferred<&'a [T; N]>> for Deferred<&'a [T]>[src]

impl<'a, T, const N: usize> From<Deferred<&'a mut [T; N]>> for Deferred<&'a mut [T]>[src]

impl<'a, T, const N: usize> From<Deferred<&'a mut [T; N]>> for Deferred<&'a [T]>[src]

impl<'a, T: ?Sized> From<Deferred<&'a mut T>> for Deferred<&'a T>[src]

impl<I, T> Index<I> for Deferred<T> where
    T: Reference,
    T::Target: SliceLike,
    I: SlicePointerIndex<T::Target>, 
[src]

type Output = I::Output

The returned type after indexing.

impl<I, T: ?Sized> IndexMut<I> for Deferred<&mut T> where
    T: SliceLike,
    I: SlicePointerIndex<T>, 
[src]

impl<T: ?Sized> Pointer for Deferred<&T>[src]

impl<T: ?Sized> Pointer for Deferred<&mut T>[src]

impl<T: Send + Reference> Send for Deferred<T>[src]

impl<T: Sync + Reference> Sync for Deferred<T>[src]

Auto Trait Implementations

impl<T> Unpin for Deferred<T>

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.