Background and motivation
This proposal lists the APIs in System.Runtime.CompilerServices.Unsafe and marks them as caller-unsafe. I'm using a diff format where + indicates that it's now caller-unsafe and - indicates the unsafe modifier has been removed (a non-breaking change).
If you are happy with this format, I'll create further proposals, likely grouped by namespace.
API Proposal
public static partial class Unsafe
{
+ public static unsafe ref T AddByteOffset<T>(ref T source, System.IntPtr byteOffset) where T : allows ref struct { throw null; }
+ public static unsafe ref T AddByteOffset<T>(ref T source, nuint byteOffset) where T : allows ref struct { throw null; }
+ public static unsafe ref T Add<T>(ref T source, int elementOffset) where T : allows ref struct { throw null; }
+ public static unsafe ref T Add<T>(ref T source, System.IntPtr elementOffset) where T : allows ref struct { throw null; }
+ public static unsafe ref T Add<T>(ref T source, nuint elementOffset) where T : allows ref struct { throw null; }
public static bool AreSame<T>([System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T left, [System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T right) where T : allows ref struct { throw null; }
+ public static unsafe ref T AsRef<T>(scoped ref readonly T source) where T : allows ref struct { throw null; }
+ public static unsafe T? As<T>(object? o) where T : class? { throw null; }
+ public static unsafe ref TTo As<TFrom, TTo>(ref TFrom source) where TFrom : allows ref struct where TTo : allows ref struct { throw null; }
+ public static unsafe TTo BitCast<TFrom, TTo>(TFrom source) where TFrom : allows ref struct where TTo : allows ref struct { throw null; }
public static System.IntPtr ByteOffset<T>([System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T origin, [System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T target) where T : allows ref struct { throw null; }
+ public static unsafe void CopyBlock(ref byte destination, ref readonly byte source, uint byteCount) { }
+ public static unsafe void CopyBlockUnaligned(ref byte destination, ref readonly byte source, uint byteCount) { }
+ public static unsafe void InitBlock(ref byte startAddress, byte value, uint byteCount) { }
+ public static unsafe void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount) { }
public static bool IsAddressGreaterThan<T>([System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T left, [System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T right) where T : allows ref struct { throw null; }
public static bool IsAddressGreaterThanOrEqualTo<T>([System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T left, [System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T right) where T : allows ref struct { throw null; }
public static bool IsAddressLessThan<T>([System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T left, [System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T right) where T : allows ref struct { throw null; }
public static bool IsAddressLessThanOrEqualTo<T>([System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T left, [System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T right) where T : allows ref struct { throw null; }
public static bool IsNullRef<T>(ref readonly T source) where T : allows ref struct { throw null; }
public static ref T NullRef<T>() where T : allows ref struct { throw null; }
+ public static unsafe T ReadUnaligned<T>(scoped ref readonly byte source) where T : allows ref struct { throw null; }
public static int SizeOf<T>() where T : allows ref struct { throw null; }
+ public static unsafe void SkipInit<T>(out T value) where T : allows ref struct { throw null; }
+ public static unsafe ref T SubtractByteOffset<T>(ref T source, System.IntPtr byteOffset) where T : allows ref struct { throw null; }
+ public static unsafe ref T SubtractByteOffset<T>(ref T source, nuint byteOffset) where T : allows ref struct { throw null; }
+ public static unsafe ref T Subtract<T>(ref T source, int elementOffset) where T : allows ref struct { throw null; }
+ public static unsafe ref T Subtract<T>(ref T source, System.IntPtr elementOffset) where T : allows ref struct { throw null; }
+ public static unsafe ref T Subtract<T>(ref T source, nuint elementOffset) where T : allows ref struct { throw null; }
+ public static unsafe ref T Unbox<T>(object box) where T : struct { throw null; }
+ public static unsafe void WriteUnaligned<T>(ref byte destination, T value) where T : allows ref struct { }
// APIs with unmanaged pointers in the signature.
- public static void* Add<T>(void* source, int elementOffset) where T : allows ref struct { throw null; }
- public static void* AsPointer<T>(ref readonly T value) where T : allows ref struct { throw null; }
public unsafe static ref T AsRef<T>(void* source) where T : allows ref struct { throw null; }
public unsafe static void CopyBlock(void* destination, void* source, uint byteCount) { }
public unsafe static void CopyBlockUnaligned(void* destination, void* source, uint byteCount) { }
public unsafe static void Copy<T>(void* destination, ref readonly T source) where T : allows ref struct { }
public unsafe static void Copy<T>(ref T destination, void* source) where T : allows ref struct { }
public unsafe static void InitBlock(void* startAddress, byte value, uint byteCount) { }
public unsafe static void InitBlockUnaligned(void* startAddress, byte value, uint byteCount) { }
public unsafe static T ReadUnaligned<T>(void* source) where T : allows ref struct { throw null; }
public unsafe static T Read<T>(void* source) where T : allows ref struct { throw null; }
- public static void* Subtract<T>(void* source, int elementOffset) where T : allows ref struct { throw null; }
public unsafe static void WriteUnaligned<T>(void* destination, T value) where T : allows ref struct { }
public unsafe static void Write<T>(void* destination, T value) where T : allows ref struct { }
}
API Usage
The annotated APIs will require unsafe{} context at their call site.
Alternative Designs
No response
Risks
No response
Background and motivation
This proposal lists the APIs in
System.Runtime.CompilerServices.Unsafeand marks them as caller-unsafe. I'm using a diff format where+indicates that it's now caller-unsafe and-indicates the unsafe modifier has been removed (a non-breaking change).If you are happy with this format, I'll create further proposals, likely grouped by namespace.
API Proposal
public static partial class Unsafe { + public static unsafe ref T AddByteOffset<T>(ref T source, System.IntPtr byteOffset) where T : allows ref struct { throw null; } + public static unsafe ref T AddByteOffset<T>(ref T source, nuint byteOffset) where T : allows ref struct { throw null; } + public static unsafe ref T Add<T>(ref T source, int elementOffset) where T : allows ref struct { throw null; } + public static unsafe ref T Add<T>(ref T source, System.IntPtr elementOffset) where T : allows ref struct { throw null; } + public static unsafe ref T Add<T>(ref T source, nuint elementOffset) where T : allows ref struct { throw null; } public static bool AreSame<T>([System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T left, [System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T right) where T : allows ref struct { throw null; } + public static unsafe ref T AsRef<T>(scoped ref readonly T source) where T : allows ref struct { throw null; } + public static unsafe T? As<T>(object? o) where T : class? { throw null; } + public static unsafe ref TTo As<TFrom, TTo>(ref TFrom source) where TFrom : allows ref struct where TTo : allows ref struct { throw null; } + public static unsafe TTo BitCast<TFrom, TTo>(TFrom source) where TFrom : allows ref struct where TTo : allows ref struct { throw null; } public static System.IntPtr ByteOffset<T>([System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T origin, [System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T target) where T : allows ref struct { throw null; } + public static unsafe void CopyBlock(ref byte destination, ref readonly byte source, uint byteCount) { } + public static unsafe void CopyBlockUnaligned(ref byte destination, ref readonly byte source, uint byteCount) { } + public static unsafe void InitBlock(ref byte startAddress, byte value, uint byteCount) { } + public static unsafe void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount) { } public static bool IsAddressGreaterThan<T>([System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T left, [System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T right) where T : allows ref struct { throw null; } public static bool IsAddressGreaterThanOrEqualTo<T>([System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T left, [System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T right) where T : allows ref struct { throw null; } public static bool IsAddressLessThan<T>([System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T left, [System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T right) where T : allows ref struct { throw null; } public static bool IsAddressLessThanOrEqualTo<T>([System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T left, [System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T right) where T : allows ref struct { throw null; } public static bool IsNullRef<T>(ref readonly T source) where T : allows ref struct { throw null; } public static ref T NullRef<T>() where T : allows ref struct { throw null; } + public static unsafe T ReadUnaligned<T>(scoped ref readonly byte source) where T : allows ref struct { throw null; } public static int SizeOf<T>() where T : allows ref struct { throw null; } + public static unsafe void SkipInit<T>(out T value) where T : allows ref struct { throw null; } + public static unsafe ref T SubtractByteOffset<T>(ref T source, System.IntPtr byteOffset) where T : allows ref struct { throw null; } + public static unsafe ref T SubtractByteOffset<T>(ref T source, nuint byteOffset) where T : allows ref struct { throw null; } + public static unsafe ref T Subtract<T>(ref T source, int elementOffset) where T : allows ref struct { throw null; } + public static unsafe ref T Subtract<T>(ref T source, System.IntPtr elementOffset) where T : allows ref struct { throw null; } + public static unsafe ref T Subtract<T>(ref T source, nuint elementOffset) where T : allows ref struct { throw null; } + public static unsafe ref T Unbox<T>(object box) where T : struct { throw null; } + public static unsafe void WriteUnaligned<T>(ref byte destination, T value) where T : allows ref struct { } // APIs with unmanaged pointers in the signature. - public static void* Add<T>(void* source, int elementOffset) where T : allows ref struct { throw null; } - public static void* AsPointer<T>(ref readonly T value) where T : allows ref struct { throw null; } public unsafe static ref T AsRef<T>(void* source) where T : allows ref struct { throw null; } public unsafe static void CopyBlock(void* destination, void* source, uint byteCount) { } public unsafe static void CopyBlockUnaligned(void* destination, void* source, uint byteCount) { } public unsafe static void Copy<T>(void* destination, ref readonly T source) where T : allows ref struct { } public unsafe static void Copy<T>(ref T destination, void* source) where T : allows ref struct { } public unsafe static void InitBlock(void* startAddress, byte value, uint byteCount) { } public unsafe static void InitBlockUnaligned(void* startAddress, byte value, uint byteCount) { } public unsafe static T ReadUnaligned<T>(void* source) where T : allows ref struct { throw null; } public unsafe static T Read<T>(void* source) where T : allows ref struct { throw null; } - public static void* Subtract<T>(void* source, int elementOffset) where T : allows ref struct { throw null; } public unsafe static void WriteUnaligned<T>(void* destination, T value) where T : allows ref struct { } public unsafe static void Write<T>(void* destination, T value) where T : allows ref struct { } }API Usage
The annotated APIs will require
unsafe{}context at their call site.Alternative Designs
No response
Risks
No response