The borrows are reference counted. The compiler sees that a function unconditionally increments the reference count at the beginning and unconditionally decrements it at the end. It further knows the semantics of reference counting, so it knows it's ok to elide both of those.
Don't know enough obj-c or swift to show an example/disassembly, but here's a suggestive quote from the llvm docs[1]
> ARC may assume that non-ARC code engages in sensible balancing behavior and does not rely on exact or minimum retain count values except as guaranteed by __strong object invariants or +1 transfer conventions. For example, if an object is provably double-retained and double-released, ARC may eliminate the inner retain and release; it does not need to guard against code which performs an unbalanced release followed by a “balancing” retain.
See also from nim[2]:
> Plain reference counting with move semantic optimizations
Don't know enough obj-c or swift to show an example/disassembly, but here's a suggestive quote from the llvm docs[1]
> ARC may assume that non-ARC code engages in sensible balancing behavior and does not rely on exact or minimum retain count values except as guaranteed by __strong object invariants or +1 transfer conventions. For example, if an object is provably double-retained and double-released, ARC may eliminate the inner retain and release; it does not need to guard against code which performs an unbalanced release followed by a “balancing” retain.
See also from nim[2]:
> Plain reference counting with move semantic optimizations
1. https://clang.llvm.org/docs/AutomaticReferenceCounting.html#...
2. https://nim-lang.org/docs/gc.html