Background and motivation
Follow up from the discussion started in #64750.
The general idea for this proposal is: with the changes to lifetime annotations for refs in C# 11, developers will be able to just do new [ReadOnly]Span(ref foo) to create a 1-length span from an arbitrary reference, which the compiler will be able to properly track. The issue remains though for arbitrary length spans, where currently the only alternative is MemoryMarshal.CreateSpan, which has the issue that does not track lifetime annotations of the input reference. This is not desireable, as in many cases the only "unsafe" component library authors want is being able to pass an arbitrary length, but without giving up on lifetime tracking.
To solve this, the proposal is for a new set of APIs that would act as a "safer" version of MemoryMarshal.CreateSpan.
The crucial difference is that the ref T parameter would not be scoped, so the compiler would see it escaping the API.
API Proposal
namespace System
{
public ref struct Span<T>
{
public static Span<T> CreateUnsafe(ref T value, int length);
}
public ref struct ReadOnlySpan<T>
{
public static ReadOnlySpan<T> CreateUnsafe(ref T value, int length);
}
}
These two APIs will also validate that the length is in the allowed range, just like the void* span constructors. The two APIs should essentially be equivalent on this front, the only difference being this will work on a tracked GC-ref and not a raw pointer.
Note: I'd be happy to be assigned this one in case it got past API review 🙂
API Usage
Just like with MemoryMarshal.CreateSpan, but with tracking.
Alternative Designs
A possible alternative could've been to break MemoryMarshal.CreateSpan and make the ref T argument a scoped ref T, but as discussed that could be problematic as there migth still be niche cases where dropping the tracking could be needed.
Risks
None, really. If anything else, this would push developers towards a safer version of MemoryMarshal.CreateSpan.
Background and motivation
The general idea for this proposal is: with the changes to lifetime annotations for refs in C# 11, developers will be able to just do
new [ReadOnly]Span(ref foo)to create a 1-length span from an arbitrary reference, which the compiler will be able to properly track. The issue remains though for arbitrary length spans, where currently the only alternative isMemoryMarshal.CreateSpan, which has the issue that does not track lifetime annotations of the input reference. This is not desireable, as in many cases the only "unsafe" component library authors want is being able to pass an arbitrary length, but without giving up on lifetime tracking.To solve this, the proposal is for a new set of APIs that would act as a "safer" version of
MemoryMarshal.CreateSpan.The crucial difference is that the
ref Tparameter would not bescoped, so the compiler would see it escaping the API.API Proposal
These two APIs will also validate that the length is in the allowed range, just like the
void*span constructors. The two APIs should essentially be equivalent on this front, the only difference being this will work on a tracked GC-ref and not a raw pointer.API Usage
Just like with
MemoryMarshal.CreateSpan, but with tracking.Alternative Designs
A possible alternative could've been to break
MemoryMarshal.CreateSpanand make theref Targument ascoped ref T, but as discussed that could be problematic as there migth still be niche cases where dropping the tracking could be needed.Risks
None, really. If anything else, this would push developers towards a safer version of
MemoryMarshal.CreateSpan.