Skip to content

[API Proposal]: [ReadOnly]Span<T>.CreateUnsafe(ref T, int) for compiler-tracked, arbitrary length spans #67242

@Sergio0694

Description

@Sergio0694

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    api-suggestionEarly API idea and discussion, it is NOT ready for implementationarea-System.Memory

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions