Skip to content

[API Proposal]: Employ allows ref struct in libraries #102671

Closed
@stephentoub

Description

@stephentoub

Background and motivation

C# 13 and .NET 9 now allow generic parameters to be annotated as where T : allows ref struct, indicating that the T may be a ref struct (expanding the allowed types that may be used as the T, as opposed to normal constraints which require that the T be the specified kind). For this to be broadly useful, we need to annotate appropriate library surface area. Any T annotated as such is then subject to all the rules of a ref struct, and it’s a breaking change to remove the allows ref struct anti-constraint, so we can only use it in places where we don’t now or won’t in the future need to store instances of the T to the heap. Developers implementing interfaces on ref structs also need to be aware that it’s a breaking change for DIMs to be added to an interface implemented on one without also overriding that DIM at the same time, since the lack of an override would result in boxing the ref struct to the interface type.

API Proposal

namespace System
{
    public delegate void Action<in T>(T obj)
+       where T : allows ref struct;

    public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2)
+       where T1 : allows ref struct
+       where T2 : allows ref struct;

    public delegate void Action<in T1, in T2, in T3>(T1 arg1, T2 arg2, T3 arg3)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct;

    public delegate void Action<in T1, in T2, in T3, in T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct;

    public delegate void Action<in T1, in T2, in T3, in T4, in T5>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct;

    public delegate void Action<in T1, in T2, in T3, in T4, in T5, in T6>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where T6 : allows ref struct;

    public delegate void Action<in T1, in T2, in T3, in T4, in T5, in T6, in T7>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where T6 : allows ref struct
+       where T7 : allows ref struct;

    public delegate void Action<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where T6 : allows ref struct
+       where T7 : allows ref struct
+       where T8 : allows ref struct;

    public delegate void Action<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where T6 : allows ref struct
+       where T7 : allows ref struct
+       where T8 : allows ref struct
+       where T9 : allows ref struct;

    public delegate void Action<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where T6 : allows ref struct
+       where T7 : allows ref struct
+       where T8 : allows ref struct
+       where T9 : allows ref struct
+       where T10 : allows ref struct;

    public delegate void Action<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where T6 : allows ref struct
+       where T7 : allows ref struct
+       where T8 : allows ref struct
+       where T9 : allows ref struct
+       where T10 : allows ref struct
+       where T11 : allows ref struct;

    public delegate void Action<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where T6 : allows ref struct
+       where T7 : allows ref struct
+       where T8 : allows ref struct
+       where T9 : allows ref struct
+       where T10 : allows ref struct
+       where T11 : allows ref struct
+       where T12 : allows ref struct;

    public delegate void Action<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where T6 : allows ref struct
+       where T7 : allows ref struct
+       where T8 : allows ref struct
+       where T9 : allows ref struct
+       where T10 : allows ref struct
+       where T11 : allows ref struct
+       where T12 : allows ref struct
+       where T13 : allows ref struct;

    public delegate void Action<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where T6 : allows ref struct
+       where T7 : allows ref struct
+       where T8 : allows ref struct
+       where T9 : allows ref struct
+       where T10 : allows ref struct
+       where T11 : allows ref struct
+       where T12 : allows ref struct
+       where T13 : allows ref struct
+       where T14 : allows ref struct;

    public delegate void Action<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where T6 : allows ref struct
+       where T7 : allows ref struct
+       where T8 : allows ref struct
+       where T9 : allows ref struct
+       where T10 : allows ref struct
+       where T11 : allows ref struct
+       where T12 : allows ref struct
+       where T13 : allows ref struct
+       where T14 : allows ref struct
+       where T15 : allows ref struct;

    public delegate void Action<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15, in T16>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where T6 : allows ref struct
+       where T7 : allows ref struct
+       where T8 : allows ref struct
+       where T9 : allows ref struct
+       where T10 : allows ref struct
+       where T11 : allows ref struct
+       where T12 : allows ref struct
+       where T13 : allows ref struct
+       where T14 : allows ref struct
+       where T15 : allows ref struct
+       where T16 : allows ref struct;

    public static class Activator
    {
        public static T CreateInstance<T>()
+           where T : allows ref struct
    }

    public delegate int Comparison<in T>(T x, T y)
+       where T : allows ref struct;

    public delegate TOutput Converter<in TInput, out TOutput>(TInput input)
+       where TInput : allows ref struct
+       where TOutput : allows ref struct;

    public delegate TResult Func<out TResult>()
+       where TResult : allows ref struct;

    public delegate TResult Func<in T, out TResult>(T arg)
+       where T : allows ref struct
+       where TResult : allows ref struct;

    public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where TResult : allows ref struct;

    public delegate TResult Func<in T1, in T2, in T3, out TResult>(T1 arg1, T2 arg2, T3 arg3)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where TResult : allows ref struct;

    public delegate TResult Func<in T1, in T2, in T3, in T4, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where TResult : allows ref struct;

    public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where TResult : allows ref struct;

    public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where T6 : allows ref struct
+       where TResult : allows ref struct;

    public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where T6 : allows ref struct
+       where T7 : allows ref struct
+       where TResult : allows ref struct;

    public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where T6 : allows ref struct
+       where T7 : allows ref struct
+       where T8 : allows ref struct
+       where TResult : allows ref struct;

    public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where T6 : allows ref struct
+       where T7 : allows ref struct
+       where T8 : allows ref struct
+       where T9 : allows ref struct
+       where TResult : allows ref struct;

    public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where T6 : allows ref struct
+       where T7 : allows ref struct
+       where T8 : allows ref struct
+       where T9 : allows ref struct
+       where T10 : allows ref struct
+       where TResult : allows ref struct;

    public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where T6 : allows ref struct
+       where T7 : allows ref struct
+       where T8 : allows ref struct
+       where T9 : allows ref struct
+       where T10 : allows ref struct
+       where T11 : allows ref struct
+       where TResult : allows ref struct;

    public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where T6 : allows ref struct
+       where T7 : allows ref struct
+       where T8 : allows ref struct
+       where T9 : allows ref struct
+       where T10 : allows ref struct
+       where T11 : allows ref struct
+       where T12 : allows ref struct
+       where TResult : allows ref struct;

    public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where T6 : allows ref struct
+       where T7 : allows ref struct
+       where T8 : allows ref struct
+       where T9 : allows ref struct
+       where T10 : allows ref struct
+       where T11 : allows ref struct
+       where T12 : allows ref struct
+       where T13 : allows ref struct
+       where TResult : allows ref struct;

    public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where T6 : allows ref struct
+       where T7 : allows ref struct
+       where T8 : allows ref struct
+       where T9 : allows ref struct
+       where T10 : allows ref struct
+       where T11 : allows ref struct
+       where T12 : allows ref struct
+       where T13 : allows ref struct
+       where T14 : allows ref struct
+       where TResult : allows ref struct;

    public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where T6 : allows ref struct
+       where T7 : allows ref struct
+       where T8 : allows ref struct
+       where T9 : allows ref struct
+       where T10 : allows ref struct
+       where T11 : allows ref struct
+       where T12 : allows ref struct
+       where T13 : allows ref struct
+       where T14 : allows ref struct
+       where T15 : allows ref struct
+       where TResult : allows ref struct;

    public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15, in T16, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16)
+       where T1 : allows ref struct
+       where T2 : allows ref struct
+       where T3 : allows ref struct
+       where T4 : allows ref struct
+       where T5 : allows ref struct
+       where T6 : allows ref struct
+       where T7 : allows ref struct
+       where T8 : allows ref struct
+       where T9 : allows ref struct
+       where T10 : allows ref struct
+       where T11 : allows ref struct
+       where T12 : allows ref struct
+       where T13 : allows ref struct
+       where T14 : allows ref struct
+       where T15 : allows ref struct
+       where T16 : allows ref struct
+       where TResult : allows ref struct;

    public delegate bool Predicate<in T>(T obj)
+       where T : allows ref struct;

    public sealed class String
    {
        public static string Create<TState>(int length, TState state, SpanAction<char, TState> action)
+           where TState : allows ref struct
    }
}

namespace System.Buffers
{
    public delegate void SpanAction<T, in TArg>(Span<T> span, TArg arg)
+       where TArg : allows ref struct;

    public delegate void ReadOnlySpanAction<T, in TArg>(ReadOnlySpan<T> span, TArg arg)
+       where TArg : allows ref struct;
}

namespace System.Collections.Concurrent
{
    public class ConcurrentDictionary<TKey, TValue>
    {
        public TValue AddOrUpdate<TArg>(TKey key, Func<TKey, TArg, TValue> addValueFactory, Func<TKey, TValue, TArg, TValue> updateValueFactory, TArg factoryArgument)
+           where TArg : allows ref struct

        public TValue GetOrAdd<TArg>(TKey key, Func<TKey, TArg, TValue> valueFactory, TArg factoryArgument)
+           where TArg : allows ref struct
    }
}

namespace System.Collections.Generic
{
   public interface IEnumerable<out T> : IEnumerable
+       where T : allows ref struct

    public interface IEnumerator<out T> : IDisposable, IEnumerator
+       where T : allows ref struct
}

namespace System.Collections.Immutable
{
    public static class ImmutableArray
    {
        public static ImmutableArray<TResult> CreateRange<TSource, TArg, TResult>(ImmutableArray<TSource> items, System.Func<TSource, TArg, TResult> selector, TArg arg)
+#if NET9_0_OR_GREATER
+           where TArg : allows ref struct
+#endif

        public static ImmutableArray<TResult> CreateRange<TSource, TArg, TResult>(ImmutableArray<TSource> items, int start, int length, Func<TSource, TArg, TResult> selector, TArg arg)
+#if NET9_0_OR_GREATER
+           where TArg : allows ref struct
+#endif
    }

    public static class ImmutableInterlocked
    {
        public static TValue GetOrAdd<TKey, TValue, TArg>(ref ImmutableDictionary<TKey, TValue> location, TKey key, System.Func<TKey, TArg, TValue> valueFactory, TArg factoryArgument) where TKey : notnull
+#if NET9_0_OR_GREATER
+           where TArg : allows ref struct
+#endif

        public static bool Update<T, TArg>(ref T location, System.Func<T, TArg, T> transformer, TArg transformerArgument) where T : class?
+#if NET9_0_OR_GREATER
+           where TArg : allows ref struct
+#endif

        public static bool Update<T, TArg>(ref ImmutableArray<T> location, Func<ImmutableArray<T>, TArg, ImmutableArray<T>> transformer, TArg transformerArgument)
+#if NET9_0_OR_GREATER
+           where TArg : allows ref struct
+#endif
    }
}

namespace System.Runtime.CompilerServices
{
    public static unsafe class Unsafe
    {
        public static void* AsPointer<T>(ref T value)
+           where T : allows ref struct

        public static int SizeOf<T>()
+           where T : allows ref struct

        public static ref TTo As<TFrom, TTo>(ref TFrom source)
+           where TFrom : allows ref struct
+           where TTo : allows ref struct

        public static ref T Add<T>(ref T source, int elementOffset)
+           where T : allows ref struct

        public static ref T Add<T>(ref T source, IntPtr elementOffset)
+           where T : allows ref struct

        public static void* Add<T>(void* source, int elementOffset)
+           where T : allows ref struct

        public static ref T Add<T>(ref T source, nuint elementOffset)
+           where T : allows ref struct

        public static ref T AddByteOffset<T>(ref T source, nuint byteOffset)
+           where T : allows ref struct

        public static bool AreSame<T>([AllowNull] ref readonly T left, [AllowNull] ref readonly T right)
+           where T : allows ref struct

        public static TTo BitCast<TFrom, TTo>(TFrom source)
+           where TFrom : allows ref struct
+           where TTo : allows ref struct

        public static void Copy<T>(void* destination, ref readonly T source)
+           where T : allows ref struct

        public static void Copy<T>(ref T destination, void* source)
+           where T : allows ref struct

        public static bool IsAddressGreaterThan<T>([AllowNull] ref readonly T left, [AllowNull] ref readonly T right)
+           where T : allows ref struct

        public static bool IsAddressLessThan<T>([AllowNull] ref readonly T left, [AllowNull] ref readonly T right)
+           where T : allows ref struct

        public static T ReadUnaligned<T>(void* source)
+           where T : allows ref struct

        public static T ReadUnaligned<T>(ref readonly byte source)
+           where T : allows ref struct

        public static void WriteUnaligned<T>(void* destination, T value)
+           where T : allows ref struct

        public static void WriteUnaligned<T>(ref byte destination, T value)
+           where T : allows ref struct

        public static ref T AddByteOffset<T>(ref T source, IntPtr byteOffset)
+           where T : allows ref struct

        public static T Read<T>(void* source)
+           where T : allows ref struct

        public static void Write<T>(void* destination, T value)
+           where T : allows ref struct

        public static ref T AsRef<T>(void* source)
+           where T : allows ref struct

        public static ref T AsRef<T>(scoped ref readonly T source)
+           where T : allows ref struct

        public static IntPtr ByteOffset<T>([AllowNull] ref readonly T origin, [AllowNull] ref readonly T target)
+           where T : allows ref struct

        public static ref T NullRef<T>()
+           where T : allows ref struct

        public static bool IsNullRef<T>(ref readonly T source)
+           where T : allows ref struct

        public static void SkipInit<T>(out T value)
+           where T : allows ref struct

        public static ref T Subtract<T>(ref T source, int elementOffset)
+           where T : allows ref struct

        public static void* Subtract<T>(void* source, int elementOffset)
+           where T : allows ref struct

        public static ref T Subtract<T>(ref T source, IntPtr elementOffset)
+           where T : allows ref struct

        public static ref T Subtract<T>(ref T source, nuint elementOffset)
+           where T : allows ref struct

        public static ref T SubtractByteOffset<T>(ref T source, IntPtr byteOffset)
+           where T : allows ref struct

        public static ref T SubtractByteOffset<T>(ref T source, nuint byteOffset)
+           where T : allows ref struct
    }
}

namespace System.Runtime.InteropServices
{
    public static class RuntimeHelpers
    {
        public static bool IsReferenceOrContainsReferences<T>()
+           where T : allows ref struct
    }
}

API Usage

e.g.

ReadOnlySpan<char> slice = ...;
string result = string.Create(slice.Length * 2, slice, (dest, slice) =>
{
    slice.CopyTo(dest);
    slice.CopyTo(dest.Slice(slice.Length);
});

Alternative Designs

n/a

Risks

No response

Metadata

Metadata

Assignees

Labels

api-approvedAPI was approved in API review, it can be implementedarea-System.RuntimeblockingMarks issues that we want to fast track in order to unblock other important workin-prThere is an active PR which will close this issue when it is merged

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions