Borrowing is the default ownership convention for most functions, but borrowing is orthogonal to whether the value is physically copied or passed by reference at the machine calling convention level. Small value types such as reference-counted pointers, integer file descriptors, etc. represent the same resource regardless of where the value is in memory (or if it's in memory at all), so borrowing them is done by passing their representation by value, but without retaining or releasing the pointer. Values of types that either do have a significant address (such as C++ types, or weak references), or are larger than a given threshold (four pointers's size), or are of unknown size (such as unspecialized generics) are passed by address.