You appear to be mixing up two different things:
- the pointer stored inside the
Span<T>
, which is indeed heavily restricted,
- what that points to, which could be absolutely anywhere.
Span<T>
does not wrap the actual area of memory it points to. It merely points to it using internal pointer and size fields.
The restrictions on Span
are so that the pointer does not leak from the stack, as it can also point to stack-allocated memory which is not allowed to leak out of the stack.
Memory<T>
on the other hand, only allows its pointer to be an array reference, which can obviously be stored anywhere as arrays are reference-type objects (classes).
For clarity: the stack here refers to the logical stack in IL used by every C# function call to store its parameters, variables and working area, not the physical stack in memory commonly used to implement that. These two things are orthogonal, although they usually coincide: it is theoretically possible that the CLR could store the logical stack on the physical heap, and for it to allocate reference-type objects on the physical stack.