Skip to content

Instantly share code, notes, and snippets.

@T-Dark0
Last active July 18, 2023 08:26
Show Gist options
  • Save T-Dark0/b14c35f44d434bd382d850a4c57f410f to your computer and use it in GitHub Desktop.
Save T-Dark0/b14c35f44d434bd382d850a4c57f410f to your computer and use it in GitHub Desktop.
What `as` does

as does a huge number of things. Probably too many. Here's a comprehensive list of everything it can do. Note that as conversions are transitive: If a as B as C compiles, then so does a as C, though it might not take the same "path" through intermediate conversions.

  • int <-> int
    • zero_extend: unsigned int -> bigger unsigned int. Pads the number with leading zeroes.
    • sign_extend: signed int -> bigger signed int. Pads the number with leading zeroes if positive, and leading ones if negative.
    • truncate: bigger int -> smaller int (regardless of signedness). Throws away the high bits of the number
    • reinterpret_sign: int -> int of the same size and opposite signedness. Does nothing to the bits.
  • int <-> float
    • cast_saturate_to_infinity: Yields the float closest to the specified integer. Yields infinity if the integer is out of bounds.
    • cast_nan_to_zero_saturating_when_out_of_bounds: Truncates the float and yields the corresponding integer. NaN yields 0, and the infinities yield the minimum and maximum integer value.
  • int <-> ptr
    • expose_addr: ptr -> int. Does nothing to the bits, and exposes the address (which is a provenance-related concept)
    • from_exposed_addr: int -> ptr. Does nothing to the bits, inheriting the provenance of a pointer with the same address that was previously exposed.
  • ptr <-> ptr
    • cast: ptr -> ptr: Does nothing to the bits, keeps the pointer's mutability while changing the type
    • cast_const -> *const T -> *mut T. Does nothing to the bits. Changes the pointer's mutability while keeping the type
    • cast_mut -> *mut T -> *const T. Does nothing to the bits. Changes the pointer's mutability while keeping the type
  • ptr <-> function pointer
    • to_fn_ptr: ptr -> fnptr. Does nothing to the bits.
    • to_data_ptr: fnptr -> ptr. Does nothing to the bits.
  • char -> u32 (this conversion only goes one way)
    • from: char -> u32. Does nothing to the bits.
  • bool -> u8 (this conversion only goes one way)
    • from: bool -> u8 Does nothing to the bits, yields 1 for true and 0 for false.
  • ref -> ptr (these conversions only go one way)
    • as_mut_ptr: &mut T -> *mut T. Does nothing to the bits.
    • as_const_ptr &T -> *const T. Does nothing to the bits.
  • ptr to sized -> ptr to unsized (that is, any pointer or reference, including Box, Arc, etc, from Ptr<T> to Ptr<U> where U does not implement Sized)
    • unsize: Makes the pointer fat. The data pointer is still stored therein, and pointee-specific metadata is added.
  • type ascription (That is, the fact that None as Option<u8> compiles)
    • ascribe: This... isn't really a function. It's more like a special inference thing.

Also, here's some special mentions:

  • char -> u8: Desugars to char -> u32 -> u8. That is, it truncates the character.
  • &mut T -> *const T. Desugars to &mut T -> &T -> *const T. Notably, this means that if the resulting pointer is cast back to *mut T, it cannot be used for writes anyway.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment