diff --git a/src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs index 6ee5eb20c8f646..f4551e01beadaf 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs @@ -170,8 +170,8 @@ public static long Add(ref long location1, long value) => /// Returns a 64-bit signed value, loaded as an atomic operation. /// The 64-bit value to be loaded. /// The loaded value. - public static long Read(ref long location) => - CompareExchange(ref location, 0, 0); + public static long Read(ref readonly long location) => + CompareExchange(ref Unsafe.AsRef(in location), 0, 0); #endregion #region MemoryBarrierProcessWide diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/CrashInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/CrashInfo.cs index af92380ee75509..8a2f33c93f1f8c 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/CrashInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/CrashInfo.cs @@ -365,7 +365,7 @@ private void CloseValue(char marker) private bool WriteSeparator() => _isCommaNeeded ? WriteChar(',') : true; - private bool WriteChar(char source) => WriteChars(new ReadOnlySpan(source)); + private bool WriteChar(char source) => WriteChars(new ReadOnlySpan(in source)); private bool WriteChars(ReadOnlySpan chars) { diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs index 85fa9a7277f5be..39a431a3bab090 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs @@ -27,9 +27,9 @@ public abstract partial class ComWrappers internal static IntPtr TaggedImplVftblPtr { get; } = CreateTaggedImplVftbl(); internal static IntPtr DefaultIReferenceTrackerTargetVftblPtr { get; } = CreateDefaultIReferenceTrackerTargetVftbl(); - internal static Guid IID_IUnknown = new Guid(0x00000000, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); - internal static Guid IID_IReferenceTrackerTarget = new Guid(0x64bd43f8, 0xbfee, 0x4ec4, 0xb7, 0xeb, 0x29, 0x35, 0x15, 0x8d, 0xae, 0x21); - internal static Guid IID_TaggedImpl = new Guid(0x5c13e51c, 0x4f32, 0x4726, 0xa3, 0xfd, 0xf3, 0xed, 0xd6, 0x3d, 0xa3, 0xa0); + internal static readonly Guid IID_IUnknown = new Guid(0x00000000, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); + internal static readonly Guid IID_IReferenceTrackerTarget = new Guid(0x64bd43f8, 0xbfee, 0x4ec4, 0xb7, 0xeb, 0x29, 0x35, 0x15, 0x8d, 0xae, 0x21); + internal static readonly Guid IID_TaggedImpl = new Guid(0x5c13e51c, 0x4f32, 0x4726, 0xa3, 0xfd, 0xf3, 0xed, 0xd6, 0x3d, 0xa3, 0xa0); private static readonly ConditionalWeakTable s_rcwTable = new ConditionalWeakTable(); @@ -46,7 +46,7 @@ public static unsafe bool TryGetComInstance(object obj, out IntPtr unknown) return false; } - return Marshal.QueryInterface(wrapper._externalComObject, ref IID_IUnknown, out unknown) == 0; + return Marshal.QueryInterface(wrapper._externalComObject, in IID_IUnknown, out unknown) == 0; } public static unsafe bool TryGetObject(IntPtr unknown, [NotNullWhen(true)] out object? obj) @@ -675,7 +675,7 @@ public object GetOrRegisterObjectForComInstance(IntPtr externalComObject, Create { // It is possible the user has defined their own IUnknown impl so // we fallback to the tagged interface approach to be sure. - if (0 != Marshal.QueryInterface(comObject, ref IID_TaggedImpl, out nint implMaybe)) + if (0 != Marshal.QueryInterface(comObject, in IID_TaggedImpl, out nint implMaybe)) { return null; } @@ -737,8 +737,7 @@ private unsafe bool TryGetOrCreateObjectForComInstanceInternal( { // The unwrapped object has a CCW in this context. Get the IUnknown for the externalComObject // so we can see if it's the CCW for the unwrapped object in this context. - Guid iid = IID_IUnknown; - int hr = Marshal.QueryInterface(externalComObject, ref iid, out IntPtr externalIUnknown); + int hr = Marshal.QueryInterface(externalComObject, in IID_IUnknown, out IntPtr externalIUnknown); Debug.Assert(hr == 0); // An external COM object that came from a ComWrappers instance // will always be well-formed. if (unwrappedWrapperInThisContext.ComIp == externalIUnknown) diff --git a/src/libraries/Common/src/Interop/Windows/SChannel/Interop.Sec_Application_Protocols.cs b/src/libraries/Common/src/Interop/Windows/SChannel/Interop.Sec_Application_Protocols.cs index 6606ee1e00bee7..281333731f46d0 100644 --- a/src/libraries/Common/src/Interop/Windows/SChannel/Interop.Sec_Application_Protocols.cs +++ b/src/libraries/Common/src/Interop/Windows/SChannel/Interop.Sec_Application_Protocols.cs @@ -54,7 +54,7 @@ public static unsafe byte[] ToByteArray(List application byte[] buffer = new byte[sizeof(Sec_Application_Protocols) + protocolListSize]; int index = 0; - MemoryMarshal.Write(buffer.AsSpan(index), ref protocols); + MemoryMarshal.Write(buffer.AsSpan(index), in protocols); index += sizeof(Sec_Application_Protocols); for (int i = 0; i < applicationProtocols.Count; i++) diff --git a/src/libraries/System.Collections.Concurrent/tests/ConcurrentDictionary/ConcurrentDictionary.Generic.Tests.cs b/src/libraries/System.Collections.Concurrent/tests/ConcurrentDictionary/ConcurrentDictionary.Generic.Tests.cs index f488444133a303..fcb69130195742 100644 --- a/src/libraries/System.Collections.Concurrent/tests/ConcurrentDictionary/ConcurrentDictionary.Generic.Tests.cs +++ b/src/libraries/System.Collections.Concurrent/tests/ConcurrentDictionary/ConcurrentDictionary.Generic.Tests.cs @@ -114,13 +114,13 @@ static T AssertNotNull(T value, [CallerArgumentExpression(nameof(value))] str uint hash1 = (5381 << 16) + 5381; uint hash2 = BitOperations.RotateLeft(hash1, 5) + hash1; - MemoryMarshal.Write(asBytes, ref seed); - MemoryMarshal.Write(asBytes.Slice(4), ref hash2); // set hash2 := 0 (for Ordinal) + MemoryMarshal.Write(asBytes, in seed); + MemoryMarshal.Write(asBytes.Slice(4), in hash2); // set hash2 := 0 (for Ordinal) hash1 = (BitOperations.RotateLeft(hash1, 5) + hash1) ^ (uint)seed; hash1 = (BitOperations.RotateLeft(hash1, 5) + hash1); - MemoryMarshal.Write(asBytes.Slice(8), ref hash1); // set hash1 := 0 (for Ordinal) + MemoryMarshal.Write(asBytes.Slice(8), in hash1); // set hash1 := 0 (for Ordinal) }); int ordinalHashCode = nonRandomizedOrdinal(candidate); diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenDictionary.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenDictionary.cs index 2e86f602f43d6d..0fab5139dc6351 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenDictionary.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenDictionary.cs @@ -431,7 +431,7 @@ void ICollection.CopyTo(Array array, int index) /// Gets either a reference to a in the dictionary or a null reference if the key does not exist in the dictionary. /// The key used for lookup. /// A reference to a in the dictionary or a null reference if the key does not exist in the dictionary. - /// The null reference can be detected by calling . + /// The null reference can be detected by calling . public ref readonly TValue GetValueRefOrNullRef(TKey key) { if (key is null) diff --git a/src/libraries/System.Collections.Immutable/tests/ImmutableArrayBuilderTest.cs b/src/libraries/System.Collections.Immutable/tests/ImmutableArrayBuilderTest.cs index 252cb0316e9a5b..3dfb5b5a4c1182 100644 --- a/src/libraries/System.Collections.Immutable/tests/ImmutableArrayBuilderTest.cs +++ b/src/libraries/System.Collections.Immutable/tests/ImmutableArrayBuilderTest.cs @@ -199,7 +199,7 @@ public void AddRangeDerivedSpan(string[] builderElements, string[] rangeElements // AddRange builder.AddRange(new ReadOnlySpan(rangeElements)); - + // Assert Assert.Equal(expectedResult, builder); } @@ -214,7 +214,7 @@ public void AddRangeDerivedImmutableArray(string[] builderElements, string[] ran // AddRange builder.AddRange(rangeElements.ToImmutableArray()); - + // Assert Assert.Equal(expectedResult, builder); } @@ -226,7 +226,7 @@ public void AddRangeDerivedBuilder(string[] builderElements, string[] rangeEleme // Initialize builder var builderBase = new ImmutableArray.Builder(); builderBase.AddRange(builderElements); - + // Prepare another builder to add var builder = new ImmutableArray.Builder(); builder.AddRange(rangeElements); @@ -1108,7 +1108,7 @@ public void ItemRef() builder.Add(3); ref readonly int safeRef = ref builder.ItemRef(1); - ref int unsafeRef = ref Unsafe.AsRef(safeRef); + ref int unsafeRef = ref Unsafe.AsRef(in safeRef); Assert.Equal(2, builder.ItemRef(1)); diff --git a/src/libraries/System.Collections.Immutable/tests/ImmutableArrayTest.cs b/src/libraries/System.Collections.Immutable/tests/ImmutableArrayTest.cs index bc7f7df4761bb8..6631b6fd61bd56 100644 --- a/src/libraries/System.Collections.Immutable/tests/ImmutableArrayTest.cs +++ b/src/libraries/System.Collections.Immutable/tests/ImmutableArrayTest.cs @@ -2552,7 +2552,7 @@ public void ItemRef() var array = new[] { 1, 2, 3 }.ToImmutableArray(); ref readonly int safeRef = ref array.ItemRef(1); - ref int unsafeRef = ref Unsafe.AsRef(safeRef); + ref int unsafeRef = ref Unsafe.AsRef(in safeRef); Assert.Equal(2, array.ItemRef(1)); diff --git a/src/libraries/System.Collections.Immutable/tests/ImmutableListBuilderTest.cs b/src/libraries/System.Collections.Immutable/tests/ImmutableListBuilderTest.cs index 897a00b40a7ddb..796af260582df2 100644 --- a/src/libraries/System.Collections.Immutable/tests/ImmutableListBuilderTest.cs +++ b/src/libraries/System.Collections.Immutable/tests/ImmutableListBuilderTest.cs @@ -228,7 +228,7 @@ public void RemoveRange() mutable.RemoveRange(new double[] { 2.4, 3.6 }); Assert.Equal(new[] { 1.5, 4.7 }, mutable); - + var absComparer = new DelegateEqualityComparer(equals: (x, y) => Math.Abs(x) == Math.Abs(y)); mutable.RemoveRange(new double[] { -1.5 }, absComparer); Assert.Equal(new[] { 4.7 }, mutable); @@ -431,7 +431,7 @@ public void ItemRef() var builder = new ImmutableList.Builder(list); ref readonly int safeRef = ref builder.ItemRef(1); - ref int unsafeRef = ref Unsafe.AsRef(safeRef); + ref int unsafeRef = ref Unsafe.AsRef(in safeRef); Assert.Equal(2, builder.ItemRef(1)); diff --git a/src/libraries/System.Collections.Immutable/tests/ImmutableListTest.cs b/src/libraries/System.Collections.Immutable/tests/ImmutableListTest.cs index 707a66ff23c863..ec569e77699464 100644 --- a/src/libraries/System.Collections.Immutable/tests/ImmutableListTest.cs +++ b/src/libraries/System.Collections.Immutable/tests/ImmutableListTest.cs @@ -820,7 +820,7 @@ public void ItemRef() ImmutableList list = new[] { 1, 2, 3 }.ToImmutableList(); ref readonly int safeRef = ref list.ItemRef(1); - ref int unsafeRef = ref Unsafe.AsRef(safeRef); + ref int unsafeRef = ref Unsafe.AsRef(in safeRef); Assert.Equal(2, list.ItemRef(1)); diff --git a/src/libraries/System.Collections.Immutable/tests/ImmutableQueueTest.cs b/src/libraries/System.Collections.Immutable/tests/ImmutableQueueTest.cs index 365240105e3404..c03621929a5990 100644 --- a/src/libraries/System.Collections.Immutable/tests/ImmutableQueueTest.cs +++ b/src/libraries/System.Collections.Immutable/tests/ImmutableQueueTest.cs @@ -268,7 +268,7 @@ public void PeekRef() .Enqueue(3); ref readonly int safeRef = ref queue.PeekRef(); - ref int unsafeRef = ref Unsafe.AsRef(safeRef); + ref int unsafeRef = ref Unsafe.AsRef(in safeRef); Assert.Equal(1, queue.PeekRef()); diff --git a/src/libraries/System.Collections.Immutable/tests/ImmutableSortedDictionaryBuilderTest.cs b/src/libraries/System.Collections.Immutable/tests/ImmutableSortedDictionaryBuilderTest.cs index a308387001dca3..6d360a4a343951 100644 --- a/src/libraries/System.Collections.Immutable/tests/ImmutableSortedDictionaryBuilderTest.cs +++ b/src/libraries/System.Collections.Immutable/tests/ImmutableSortedDictionaryBuilderTest.cs @@ -286,7 +286,7 @@ public void ValueRef() }.ToImmutableSortedDictionary().ToBuilder(); ref readonly int safeRef = ref builder.ValueRef("a"); - ref int unsafeRef = ref Unsafe.AsRef(safeRef); + ref int unsafeRef = ref Unsafe.AsRef(in safeRef); Assert.Equal(1, builder.ValueRef("a")); diff --git a/src/libraries/System.Collections.Immutable/tests/ImmutableSortedDictionaryTest.cs b/src/libraries/System.Collections.Immutable/tests/ImmutableSortedDictionaryTest.cs index 908179061b067f..492d319e2c3db0 100644 --- a/src/libraries/System.Collections.Immutable/tests/ImmutableSortedDictionaryTest.cs +++ b/src/libraries/System.Collections.Immutable/tests/ImmutableSortedDictionaryTest.cs @@ -434,7 +434,7 @@ public void ValueRef() }.ToImmutableSortedDictionary(); ref readonly int safeRef = ref dictionary.ValueRef("a"); - ref int unsafeRef = ref Unsafe.AsRef(safeRef); + ref int unsafeRef = ref Unsafe.AsRef(in safeRef); Assert.Equal(1, dictionary.ValueRef("a")); diff --git a/src/libraries/System.Collections.Immutable/tests/ImmutableSortedSetBuilderTest.nonnetstandard.cs b/src/libraries/System.Collections.Immutable/tests/ImmutableSortedSetBuilderTest.nonnetstandard.cs index 353efec5c832cc..7b8dc5b37787dd 100644 --- a/src/libraries/System.Collections.Immutable/tests/ImmutableSortedSetBuilderTest.nonnetstandard.cs +++ b/src/libraries/System.Collections.Immutable/tests/ImmutableSortedSetBuilderTest.nonnetstandard.cs @@ -19,7 +19,7 @@ public void ItemRef() var builder = new ImmutableSortedSet.Builder(array); ref readonly int safeRef = ref builder.ItemRef(1); - ref int unsafeRef = ref Unsafe.AsRef(safeRef); + ref int unsafeRef = ref Unsafe.AsRef(in safeRef); Assert.Equal(2, builder.ItemRef(1)); diff --git a/src/libraries/System.Collections.Immutable/tests/ImmutableSortedSetTest.cs b/src/libraries/System.Collections.Immutable/tests/ImmutableSortedSetTest.cs index 1f6808c4f69618..eecff21ffb34b7 100644 --- a/src/libraries/System.Collections.Immutable/tests/ImmutableSortedSetTest.cs +++ b/src/libraries/System.Collections.Immutable/tests/ImmutableSortedSetTest.cs @@ -410,7 +410,7 @@ public void ItemRef() var array = new[] { 1, 2, 3 }.ToImmutableSortedSet(); ref readonly int safeRef = ref array.ItemRef(1); - ref int unsafeRef = ref Unsafe.AsRef(safeRef); + ref int unsafeRef = ref Unsafe.AsRef(in safeRef); Assert.Equal(2, array.ItemRef(1)); diff --git a/src/libraries/System.Collections.Immutable/tests/ImmutableStackTest.cs b/src/libraries/System.Collections.Immutable/tests/ImmutableStackTest.cs index 1813326705ef50..26336209e12047 100644 --- a/src/libraries/System.Collections.Immutable/tests/ImmutableStackTest.cs +++ b/src/libraries/System.Collections.Immutable/tests/ImmutableStackTest.cs @@ -285,7 +285,7 @@ public void PeekRef() .Push(3); ref readonly int safeRef = ref stack.PeekRef(); - ref int unsafeRef = ref Unsafe.AsRef(safeRef); + ref int unsafeRef = ref Unsafe.AsRef(in safeRef); Assert.Equal(3, stack.PeekRef()); diff --git a/src/libraries/System.Collections/tests/Generic/Dictionary/HashCollisionScenarios/OutOfBoundsRegression.cs b/src/libraries/System.Collections/tests/Generic/Dictionary/HashCollisionScenarios/OutOfBoundsRegression.cs index a95b7ff2485a62..a41ed79d680785 100644 --- a/src/libraries/System.Collections/tests/Generic/Dictionary/HashCollisionScenarios/OutOfBoundsRegression.cs +++ b/src/libraries/System.Collections/tests/Generic/Dictionary/HashCollisionScenarios/OutOfBoundsRegression.cs @@ -303,13 +303,13 @@ static string GenerateCollidingStringCandidate(int seed) uint hash1 = (5381 << 16) + 5381; uint hash2 = BitOperations.RotateLeft(hash1, 5) + hash1; - MemoryMarshal.Write(asBytes, ref seed); - MemoryMarshal.Write(asBytes.Slice(4), ref hash2); // set hash2 := 0 (for Ordinal) + MemoryMarshal.Write(asBytes, in seed); + MemoryMarshal.Write(asBytes.Slice(4), in hash2); // set hash2 := 0 (for Ordinal) hash1 = (BitOperations.RotateLeft(hash1, 5) + hash1) ^ (uint)seed; hash1 = (BitOperations.RotateLeft(hash1, 5) + hash1); - MemoryMarshal.Write(asBytes.Slice(8), ref hash1); // set hash1 := 0 (for Ordinal) + MemoryMarshal.Write(asBytes.Slice(8), in hash1); // set hash1 := 0 (for Ordinal) }); } } diff --git a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs index 44922cfabe1783..0bb57ff7f67aef 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs @@ -8,6 +8,10 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +// We need to target netstandard2.0, so keep using ref for MemoryMarshal.Write +// CS9191: The 'ref' modifier for argument 2 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead. +#pragma warning disable CS9191 + namespace System.Data.OleDb { /// diff --git a/src/libraries/System.Data.OleDb/src/SafeHandles.cs b/src/libraries/System.Data.OleDb/src/SafeHandles.cs index c976194b0c431f..3ebcca1c9d3615 100644 --- a/src/libraries/System.Data.OleDb/src/SafeHandles.cs +++ b/src/libraries/System.Data.OleDb/src/SafeHandles.cs @@ -9,6 +9,10 @@ using System.Runtime.Versioning; using static System.Data.Common.UnsafeNativeMethods; +// We need to target netstandard2.0, so keep using ref for MemoryMarshal.Write +// CS9191: The 'ref' modifier for argument 2 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead. +#pragma warning disable CS9191 + namespace System.Data.OleDb { internal sealed class DualCoTaskMem : SafeHandle diff --git a/src/libraries/System.Management/src/System/Management/InteropClasses/WMIInterop.cs b/src/libraries/System.Management/src/System/Management/InteropClasses/WMIInterop.cs index 771c16184465ed..16e65902005020 100644 --- a/src/libraries/System.Management/src/System/Management/InteropClasses/WMIInterop.cs +++ b/src/libraries/System.Management/src/System/Management/InteropClasses/WMIInterop.cs @@ -9,6 +9,10 @@ using System.Runtime.Versioning; using System.Text; +// We need to target netstandard2.0, so keep using ref for MemoryMarshal.Write +// CS9191: The 'ref' modifier for argument 2 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead. +#pragma warning disable CS9191 + namespace WbemClient_v1 { } namespace WbemUtilities_v1 { } diff --git a/src/libraries/System.Management/src/System/Management/wmiutil.cs b/src/libraries/System.Management/src/System/Management/wmiutil.cs index 05326c160d43e2..3c0ce96e4cd084 100644 --- a/src/libraries/System.Management/src/System/Management/wmiutil.cs +++ b/src/libraries/System.Management/src/System/Management/wmiutil.cs @@ -3,6 +3,10 @@ using System.Runtime.InteropServices; +// We need to target netstandard2.0, so keep using ref for MemoryMarshal.Write +// CS9191: The 'ref' modifier for argument 2 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead. +#pragma warning disable CS9191 + namespace System.Management { diff --git a/src/libraries/System.Memory/ref/System.Memory.cs b/src/libraries/System.Memory/ref/System.Memory.cs index eef0f940d10823..ce19bc6cbde037 100644 --- a/src/libraries/System.Memory/ref/System.Memory.cs +++ b/src/libraries/System.Memory/ref/System.Memory.cs @@ -693,7 +693,7 @@ public static partial class MemoryMarshal public static System.ReadOnlySpan Cast(System.ReadOnlySpan span) where TFrom : struct where TTo : struct { throw null; } public static System.Span Cast(System.Span span) where TFrom : struct where TTo : struct { throw null; } public static System.Memory CreateFromPinnedArray(T[]? array, int start, int length) { throw null; } - public static System.ReadOnlySpan CreateReadOnlySpan(scoped ref T reference, int length) { throw null; } + public static System.ReadOnlySpan CreateReadOnlySpan(scoped ref readonly T reference, int length) { throw null; } [System.CLSCompliant(false)] public static unsafe ReadOnlySpan CreateReadOnlySpanFromNullTerminated(byte* value) { throw null; } [System.CLSCompliant(false)] @@ -710,8 +710,8 @@ public static partial class MemoryMarshal public static bool TryGetMemoryManager(System.ReadOnlyMemory memory, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TManager? manager, out int start, out int length) where TManager : System.Buffers.MemoryManager { throw null; } public static bool TryGetString(System.ReadOnlyMemory memory, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out string? text, out int start, out int length) { throw null; } public static bool TryRead(System.ReadOnlySpan source, out T value) where T : struct { throw null; } - public static bool TryWrite(System.Span destination, ref T value) where T : struct { throw null; } - public static void Write(System.Span destination, ref T value) where T : struct { } + public static bool TryWrite(System.Span destination, in T value) where T : struct { throw null; } + public static void Write(System.Span destination, in T value) where T : struct { } } } namespace System.Text diff --git a/src/libraries/System.Memory/src/System/Buffers/SequenceReader.cs b/src/libraries/System.Memory/src/System/Buffers/SequenceReader.cs index 78de8a555c89a2..b574a7298c6f0e 100644 --- a/src/libraries/System.Memory/src/System/Buffers/SequenceReader.cs +++ b/src/libraries/System.Memory/src/System/Buffers/SequenceReader.cs @@ -99,7 +99,7 @@ public readonly long Length if (_length < 0) { // Cast-away readonly to initialize lazy field - Unsafe.AsRef(_length) = Sequence.Length; + Unsafe.AsRef(in _length) = Sequence.Length; } return _length; } diff --git a/src/libraries/System.Memory/tests/Binary/BinaryWriterUnitTests.cs b/src/libraries/System.Memory/tests/Binary/BinaryWriterUnitTests.cs index 2f9011470521aa..67260a4b54e82a 100644 --- a/src/libraries/System.Memory/tests/Binary/BinaryWriterUnitTests.cs +++ b/src/libraries/System.Memory/tests/Binary/BinaryWriterUnitTests.cs @@ -17,69 +17,69 @@ public void SpanWrite() Span span = new byte[8]; byte byteValue = 0x11; - MemoryMarshal.Write(span, ref byteValue); + MemoryMarshal.Write(span, in byteValue); TestHelpers.Validate(span, byteValue); - Assert.True(MemoryMarshal.TryWrite(span, ref byteValue)); + Assert.True(MemoryMarshal.TryWrite(span, in byteValue)); TestHelpers.Validate(span, byteValue); sbyte sbyteValue = 0x11; - MemoryMarshal.Write(span, ref sbyteValue); + MemoryMarshal.Write(span, in sbyteValue); TestHelpers.Validate(span, sbyteValue); - Assert.True(MemoryMarshal.TryWrite(span, ref sbyteValue)); + Assert.True(MemoryMarshal.TryWrite(span, in sbyteValue)); TestHelpers.Validate(span, sbyteValue); ushort ushortValue = 0x1122; - MemoryMarshal.Write(span, ref ushortValue); + MemoryMarshal.Write(span, in ushortValue); TestHelpers.Validate(span, ushortValue); - Assert.True(MemoryMarshal.TryWrite(span, ref ushortValue)); + Assert.True(MemoryMarshal.TryWrite(span, in ushortValue)); TestHelpers.Validate(span, ushortValue); uint uintValue = 0x11223344; - MemoryMarshal.Write(span, ref uintValue); + MemoryMarshal.Write(span, in uintValue); TestHelpers.Validate(span, uintValue); - Assert.True(MemoryMarshal.TryWrite(span, ref uintValue)); + Assert.True(MemoryMarshal.TryWrite(span, in uintValue)); TestHelpers.Validate(span, uintValue); ulong ulongValue = 0x1122334455667788; - MemoryMarshal.Write(span, ref ulongValue); + MemoryMarshal.Write(span, in ulongValue); TestHelpers.Validate(span, ulongValue); - Assert.True(MemoryMarshal.TryWrite(span, ref ulongValue)); + Assert.True(MemoryMarshal.TryWrite(span, in ulongValue)); TestHelpers.Validate(span, ulongValue); short shortValue = 0x1122; - MemoryMarshal.Write(span, ref shortValue); + MemoryMarshal.Write(span, in shortValue); TestHelpers.Validate(span, shortValue); - Assert.True(MemoryMarshal.TryWrite(span, ref shortValue)); + Assert.True(MemoryMarshal.TryWrite(span, in shortValue)); TestHelpers.Validate(span, shortValue); int intValue = 0x11223344; - MemoryMarshal.Write(span, ref intValue); + MemoryMarshal.Write(span, in intValue); TestHelpers.Validate(span, intValue); - Assert.True(MemoryMarshal.TryWrite(span, ref intValue)); + Assert.True(MemoryMarshal.TryWrite(span, in intValue)); TestHelpers.Validate(span, intValue); long longValue = 0x1122334455667788; - MemoryMarshal.Write(span, ref longValue); + MemoryMarshal.Write(span, in longValue); TestHelpers.Validate(span, longValue); - Assert.True(MemoryMarshal.TryWrite(span, ref longValue)); + Assert.True(MemoryMarshal.TryWrite(span, in longValue)); TestHelpers.Validate(span, longValue); Half halfValue = BitConverter.Int16BitsToHalf(0x1122); - MemoryMarshal.Write(span, ref halfValue); + MemoryMarshal.Write(span, in halfValue); TestHelpers.Validate(span, halfValue); - Assert.True(MemoryMarshal.TryWrite(span, ref halfValue)); + Assert.True(MemoryMarshal.TryWrite(span, in halfValue)); TestHelpers.Validate(span, halfValue); float floatValue = BitConverter.Int32BitsToSingle(0x11223344); - MemoryMarshal.Write(span, ref floatValue); + MemoryMarshal.Write(span, in floatValue); TestHelpers.Validate(span, floatValue); - Assert.True(MemoryMarshal.TryWrite(span, ref floatValue)); + Assert.True(MemoryMarshal.TryWrite(span, in floatValue)); TestHelpers.Validate(span, floatValue); double doubleValue = BitConverter.Int64BitsToDouble(0x1122334455667788); - MemoryMarshal.Write(span, ref doubleValue); + MemoryMarshal.Write(span, in doubleValue); TestHelpers.Validate(span, doubleValue); - Assert.True(MemoryMarshal.TryWrite(span, ref doubleValue)); + Assert.True(MemoryMarshal.TryWrite(span, in doubleValue)); TestHelpers.Validate(span, doubleValue); } @@ -380,48 +380,48 @@ public void SpanWriteFail() Span span = new byte[1]; - MemoryMarshal.Write(span, ref byteValue); + MemoryMarshal.Write(span, in byteValue); byte read = MemoryMarshal.Read(span); Assert.Equal(byteValue, read); span.Clear(); - Assert.True(MemoryMarshal.TryWrite(span, ref byteValue)); + Assert.True(MemoryMarshal.TryWrite(span, in byteValue)); read = MemoryMarshal.Read(span); Assert.Equal(byteValue, read); - MemoryMarshal.Write(span, ref sbyteValue); + MemoryMarshal.Write(span, in sbyteValue); sbyte readSbyte = MemoryMarshal.Read(span); Assert.Equal(sbyteValue, readSbyte); span.Clear(); - Assert.True(MemoryMarshal.TryWrite(span, ref sbyteValue)); + Assert.True(MemoryMarshal.TryWrite(span, in sbyteValue)); readSbyte = MemoryMarshal.Read(span); Assert.Equal(sbyteValue, readSbyte); - TestHelpers.AssertThrows(span, (_span) => MemoryMarshal.Write(_span, ref shortValue)); - Assert.False(MemoryMarshal.TryWrite(span, ref shortValue)); - TestHelpers.AssertThrows(span, (_span) => MemoryMarshal.Write(_span, ref intValue)); - Assert.False(MemoryMarshal.TryWrite(span, ref intValue)); - TestHelpers.AssertThrows(span, (_span) => MemoryMarshal.Write(_span, ref longValue)); - Assert.False(MemoryMarshal.TryWrite(span, ref longValue)); - - TestHelpers.AssertThrows(span, (_span) => MemoryMarshal.Write(_span, ref ushortValue)); - Assert.False(MemoryMarshal.TryWrite(span, ref ushortValue)); - TestHelpers.AssertThrows(span, (_span) => MemoryMarshal.Write(_span, ref uintValue)); - Assert.False(MemoryMarshal.TryWrite(span, ref uintValue)); - TestHelpers.AssertThrows(span, (_span) => MemoryMarshal.Write(_span, ref ulongValue)); - Assert.False(MemoryMarshal.TryWrite(span, ref ulongValue)); - - TestHelpers.AssertThrows(span, (_span) => MemoryMarshal.Write(_span, ref halfValue)); - Assert.False(MemoryMarshal.TryWrite(span, ref halfValue)); - TestHelpers.AssertThrows(span, (_span) => MemoryMarshal.Write(_span, ref floatValue)); - Assert.False(MemoryMarshal.TryWrite(span, ref floatValue)); - TestHelpers.AssertThrows(span, (_span) => MemoryMarshal.Write(_span, ref doubleValue)); - Assert.False(MemoryMarshal.TryWrite(span, ref doubleValue)); + TestHelpers.AssertThrows(span, (_span) => MemoryMarshal.Write(_span, in shortValue)); + Assert.False(MemoryMarshal.TryWrite(span, in shortValue)); + TestHelpers.AssertThrows(span, (_span) => MemoryMarshal.Write(_span, in intValue)); + Assert.False(MemoryMarshal.TryWrite(span, in intValue)); + TestHelpers.AssertThrows(span, (_span) => MemoryMarshal.Write(_span, in longValue)); + Assert.False(MemoryMarshal.TryWrite(span, in longValue)); + + TestHelpers.AssertThrows(span, (_span) => MemoryMarshal.Write(_span, in ushortValue)); + Assert.False(MemoryMarshal.TryWrite(span, in ushortValue)); + TestHelpers.AssertThrows(span, (_span) => MemoryMarshal.Write(_span, in uintValue)); + Assert.False(MemoryMarshal.TryWrite(span, in uintValue)); + TestHelpers.AssertThrows(span, (_span) => MemoryMarshal.Write(_span, in ulongValue)); + Assert.False(MemoryMarshal.TryWrite(span, in ulongValue)); + + TestHelpers.AssertThrows(span, (_span) => MemoryMarshal.Write(_span, in halfValue)); + Assert.False(MemoryMarshal.TryWrite(span, in halfValue)); + TestHelpers.AssertThrows(span, (_span) => MemoryMarshal.Write(_span, in floatValue)); + Assert.False(MemoryMarshal.TryWrite(span, in floatValue)); + TestHelpers.AssertThrows(span, (_span) => MemoryMarshal.Write(_span, in doubleValue)); + Assert.False(MemoryMarshal.TryWrite(span, in doubleValue)); var structValue = new TestHelpers.TestValueTypeWithReference { I = 1, S = "1" }; - TestHelpers.AssertThrows(span, (_span) => MemoryMarshal.Write(_span, ref structValue)); - TestHelpers.AssertThrows(span, (_span) => MemoryMarshal.TryWrite(_span, ref structValue)); + TestHelpers.AssertThrows(span, (_span) => MemoryMarshal.Write(_span, in structValue)); + TestHelpers.AssertThrows(span, (_span) => MemoryMarshal.TryWrite(_span, in structValue)); } } } diff --git a/src/libraries/System.Memory/tests/Span/IndexOfAny.T.cs b/src/libraries/System.Memory/tests/Span/IndexOfAny.T.cs index baf2edc14ccc7b..932e2e528babde 100644 --- a/src/libraries/System.Memory/tests/Span/IndexOfAny.T.cs +++ b/src/libraries/System.Memory/tests/Span/IndexOfAny.T.cs @@ -1005,7 +1005,7 @@ private static int IndexOf(Span span, T value) where T : IEquatable? Assert.Equal(index >= 0, span.Contains(value)); Assert.Equal(index >= 0, ((ReadOnlySpan)span).Contains(value)); - AssertSearchValues(span, new ReadOnlySpan(value), index); + AssertSearchValues(span, new ReadOnlySpan(in value), index); return index; } diff --git a/src/libraries/System.Net.Http/tests/UnitTests/HttpRuleParserTest.cs b/src/libraries/System.Net.Http/tests/UnitTests/HttpRuleParserTest.cs index 29e49940251073..8efca2f7ff2887 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/HttpRuleParserTest.cs +++ b/src/libraries/System.Net.Http/tests/UnitTests/HttpRuleParserTest.cs @@ -44,7 +44,8 @@ public static IEnumerable InvalidTokenCharsArguments public void IsToken_ValidTokenChars_ConsideredValid(char token) { Assert.True(HttpRuleParser.IsToken(stackalloc[] { token })); - Assert.True(HttpRuleParser.IsToken(new ReadOnlySpan((byte)token))); + var byteToken = (byte)token; + Assert.True(HttpRuleParser.IsToken(new ReadOnlySpan(in byteToken))); } [Theory] @@ -52,7 +53,8 @@ public void IsToken_ValidTokenChars_ConsideredValid(char token) public void IsToken_InvalidTokenChars_ConsideredInvalid(char token) { Assert.False(HttpRuleParser.IsToken(stackalloc[] { token })); - Assert.False(HttpRuleParser.IsToken(new ReadOnlySpan((byte)token))); + var byteToken = (byte)token; + Assert.False(HttpRuleParser.IsToken(new ReadOnlySpan(in byteToken))); } [Fact] diff --git a/src/libraries/System.Net.Primitives/src/System/Net/IPAddress.cs b/src/libraries/System.Net.Primitives/src/System/Net/IPAddress.cs index 66d233cd98194e..a4c0dc55200196 100644 --- a/src/libraries/System.Net.Primitives/src/System/Net/IPAddress.cs +++ b/src/libraries/System.Net.Primitives/src/System/Net/IPAddress.cs @@ -331,7 +331,7 @@ private void WriteIPv6Bytes(Span destination) private void WriteIPv4Bytes(Span destination) { uint address = PrivateAddress; - MemoryMarshal.Write(destination, ref address); + MemoryMarshal.Write(destination, in address); } /// diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs index 2cf92d6051437f..45e77f49b6ecda 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs @@ -45,13 +45,16 @@ public static Exception GetException(SecurityStatusPal status) internal const bool StartMutualAuthAsAnonymous = true; internal const bool CanEncryptEmptyMessage = true; - private static readonly byte[] s_sessionTokenBuffer = MemoryMarshal.AsBytes(new ReadOnlySpan( - new Interop.SChannel.SCHANNEL_SESSION_TOKEN() - { + private static readonly byte[] s_sessionTokenBuffer = InitSessionTokenBuffer(); + + private static byte[] InitSessionTokenBuffer() + { + var schannelSessionToken = new Interop.SChannel.SCHANNEL_SESSION_TOKEN() { dwTokenType = Interop.SChannel.SCHANNEL_SESSION, dwFlags = Interop.SChannel.SSL_SESSION_DISABLE_RECONNECTS, - } - )).ToArray(); + }; + return MemoryMarshal.AsBytes(new ReadOnlySpan(in schannelSessionToken)).ToArray(); + } public static void VerifyPackageInfo() { diff --git a/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs b/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs index 4222adb42047bc..54aa3bed572b97 100644 --- a/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs +++ b/src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs @@ -292,9 +292,9 @@ public static partial class Vector [System.CLSCompliantAttribute(false)] public static unsafe System.Numerics.Vector LoadAlignedNonTemporal(T* source) { throw null; } #pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type ('T') - public static System.Numerics.Vector LoadUnsafe(ref T source) { throw null; } + public static System.Numerics.Vector LoadUnsafe(ref readonly T source) { throw null; } [System.CLSCompliantAttribute(false)] - public static System.Numerics.Vector LoadUnsafe(ref T source, nuint elementOffset) { throw null; } + public static System.Numerics.Vector LoadUnsafe(ref readonly T source, nuint elementOffset) { throw null; } public static System.Numerics.Vector Max(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector Min(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector Multiply(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Boolean.cs b/src/libraries/System.Private.CoreLib/src/System/Boolean.cs index 7d9ff445d6b3f3..07db907c2b1ed3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Boolean.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Boolean.cs @@ -99,7 +99,7 @@ public bool TryFormat(Span destination, out int charsWritten) if (destination.Length > 3) { ulong true_val = BitConverter.IsLittleEndian ? 0x65007500720054ul : 0x54007200750065ul; // "True" - MemoryMarshal.Write(MemoryMarshal.AsBytes(destination), ref true_val); + MemoryMarshal.Write(MemoryMarshal.AsBytes(destination), in true_val); charsWritten = 4; return true; } @@ -109,7 +109,7 @@ public bool TryFormat(Span destination, out int charsWritten) if (destination.Length > 4) { ulong fals_val = BitConverter.IsLittleEndian ? 0x73006C00610046ul : 0x460061006C0073ul; // "Fals" - MemoryMarshal.Write(MemoryMarshal.AsBytes(destination), ref fals_val); + MemoryMarshal.Write(MemoryMarshal.AsBytes(destination), in fals_val); destination[4] = 'e'; charsWritten = 5; return true; diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.WriteBigEndian.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.WriteBigEndian.cs index a30ff594e04be4..67602e99a7fc38 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.WriteBigEndian.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.WriteBigEndian.cs @@ -23,11 +23,11 @@ public static void WriteDoubleBigEndian(Span destination, double value) if (BitConverter.IsLittleEndian) { long tmp = ReverseEndianness(BitConverter.DoubleToInt64Bits(value)); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -46,11 +46,11 @@ public static void WriteHalfBigEndian(Span destination, Half value) if (BitConverter.IsLittleEndian) { short tmp = ReverseEndianness(BitConverter.HalfToInt16Bits(value)); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -63,11 +63,11 @@ public static void WriteInt16BigEndian(Span destination, short value) if (BitConverter.IsLittleEndian) { short tmp = ReverseEndianness(value); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -80,11 +80,11 @@ public static void WriteInt32BigEndian(Span destination, int value) if (BitConverter.IsLittleEndian) { int tmp = ReverseEndianness(value); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -97,11 +97,11 @@ public static void WriteInt64BigEndian(Span destination, long value) if (BitConverter.IsLittleEndian) { long tmp = ReverseEndianness(value); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -114,11 +114,11 @@ public static void WriteInt128BigEndian(Span destination, Int128 value) if (BitConverter.IsLittleEndian) { Int128 tmp = ReverseEndianness(value); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -131,11 +131,11 @@ public static void WriteIntPtrBigEndian(Span destination, nint value) if (BitConverter.IsLittleEndian) { nint tmp = ReverseEndianness(value); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -154,11 +154,11 @@ public static void WriteSingleBigEndian(Span destination, float value) if (BitConverter.IsLittleEndian) { int tmp = ReverseEndianness(BitConverter.SingleToInt32Bits(value)); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -172,11 +172,11 @@ public static void WriteUInt16BigEndian(Span destination, ushort value) if (BitConverter.IsLittleEndian) { ushort tmp = ReverseEndianness(value); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -190,11 +190,11 @@ public static void WriteUInt32BigEndian(Span destination, uint value) if (BitConverter.IsLittleEndian) { uint tmp = ReverseEndianness(value); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -208,11 +208,11 @@ public static void WriteUInt64BigEndian(Span destination, ulong value) if (BitConverter.IsLittleEndian) { ulong tmp = ReverseEndianness(value); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -226,11 +226,11 @@ public static void WriteUInt128BigEndian(Span destination, UInt128 value) if (BitConverter.IsLittleEndian) { UInt128 tmp = ReverseEndianness(value); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -244,11 +244,11 @@ public static void WriteUIntPtrBigEndian(Span destination, nuint value) if (BitConverter.IsLittleEndian) { nuint tmp = ReverseEndianness(value); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -267,10 +267,10 @@ public static bool TryWriteDoubleBigEndian(Span destination, double value) if (BitConverter.IsLittleEndian) { long tmp = ReverseEndianness(BitConverter.DoubleToInt64Bits(value)); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -288,10 +288,10 @@ public static bool TryWriteHalfBigEndian(Span destination, Half value) if (BitConverter.IsLittleEndian) { short tmp = ReverseEndianness(BitConverter.HalfToInt16Bits(value)); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -304,10 +304,10 @@ public static bool TryWriteInt16BigEndian(Span destination, short value) if (BitConverter.IsLittleEndian) { short tmp = ReverseEndianness(value); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -320,10 +320,10 @@ public static bool TryWriteInt32BigEndian(Span destination, int value) if (BitConverter.IsLittleEndian) { int tmp = ReverseEndianness(value); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -336,10 +336,10 @@ public static bool TryWriteInt64BigEndian(Span destination, long value) if (BitConverter.IsLittleEndian) { long tmp = ReverseEndianness(value); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -352,10 +352,10 @@ public static bool TryWriteInt128BigEndian(Span destination, Int128 value) if (BitConverter.IsLittleEndian) { Int128 tmp = ReverseEndianness(value); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -368,10 +368,10 @@ public static bool TryWriteIntPtrBigEndian(Span destination, nint value) if (BitConverter.IsLittleEndian) { nint tmp = ReverseEndianness(value); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -389,10 +389,10 @@ public static bool TryWriteSingleBigEndian(Span destination, float value) if (BitConverter.IsLittleEndian) { int tmp = ReverseEndianness(BitConverter.SingleToInt32Bits(value)); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -406,10 +406,10 @@ public static bool TryWriteUInt16BigEndian(Span destination, ushort value) if (BitConverter.IsLittleEndian) { ushort tmp = ReverseEndianness(value); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -423,10 +423,10 @@ public static bool TryWriteUInt32BigEndian(Span destination, uint value) if (BitConverter.IsLittleEndian) { uint tmp = ReverseEndianness(value); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -440,10 +440,10 @@ public static bool TryWriteUInt64BigEndian(Span destination, ulong value) if (BitConverter.IsLittleEndian) { ulong tmp = ReverseEndianness(value); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -457,10 +457,10 @@ public static bool TryWriteUInt128BigEndian(Span destination, UInt128 valu if (BitConverter.IsLittleEndian) { UInt128 tmp = ReverseEndianness(value); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -474,10 +474,10 @@ public static bool TryWriteUIntPtrBigEndian(Span destination, nuint value) if (BitConverter.IsLittleEndian) { nuint tmp = ReverseEndianness(value); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.WriteLittleEndian.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.WriteLittleEndian.cs index efba216e68b438..f8a92a3e4dc489 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.WriteLittleEndian.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.WriteLittleEndian.cs @@ -23,11 +23,11 @@ public static void WriteDoubleLittleEndian(Span destination, double value) if (!BitConverter.IsLittleEndian) { long tmp = ReverseEndianness(BitConverter.DoubleToInt64Bits(value)); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -46,11 +46,11 @@ public static void WriteHalfLittleEndian(Span destination, Half value) if (!BitConverter.IsLittleEndian) { short tmp = ReverseEndianness(BitConverter.HalfToInt16Bits(value)); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -63,11 +63,11 @@ public static void WriteInt16LittleEndian(Span destination, short value) if (!BitConverter.IsLittleEndian) { short tmp = ReverseEndianness(value); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -80,11 +80,11 @@ public static void WriteInt32LittleEndian(Span destination, int value) if (!BitConverter.IsLittleEndian) { int tmp = ReverseEndianness(value); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -97,11 +97,11 @@ public static void WriteInt64LittleEndian(Span destination, long value) if (!BitConverter.IsLittleEndian) { long tmp = ReverseEndianness(value); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -114,11 +114,11 @@ public static void WriteInt128LittleEndian(Span destination, Int128 value) if (!BitConverter.IsLittleEndian) { Int128 tmp = ReverseEndianness(value); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -131,11 +131,11 @@ public static void WriteIntPtrLittleEndian(Span destination, nint value) if (!BitConverter.IsLittleEndian) { nint tmp = ReverseEndianness(value); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -154,11 +154,11 @@ public static void WriteSingleLittleEndian(Span destination, float value) if (!BitConverter.IsLittleEndian) { int tmp = ReverseEndianness(BitConverter.SingleToInt32Bits(value)); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -172,11 +172,11 @@ public static void WriteUInt16LittleEndian(Span destination, ushort value) if (!BitConverter.IsLittleEndian) { ushort tmp = ReverseEndianness(value); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -190,11 +190,11 @@ public static void WriteUInt32LittleEndian(Span destination, uint value) if (!BitConverter.IsLittleEndian) { uint tmp = ReverseEndianness(value); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -208,11 +208,11 @@ public static void WriteUInt64LittleEndian(Span destination, ulong value) if (!BitConverter.IsLittleEndian) { ulong tmp = ReverseEndianness(value); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -226,11 +226,11 @@ public static void WriteUInt128LittleEndian(Span destination, UInt128 valu if (!BitConverter.IsLittleEndian) { UInt128 tmp = ReverseEndianness(value); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -244,11 +244,11 @@ public static void WriteUIntPtrLittleEndian(Span destination, nuint value) if (!BitConverter.IsLittleEndian) { nuint tmp = ReverseEndianness(value); - MemoryMarshal.Write(destination, ref tmp); + MemoryMarshal.Write(destination, in tmp); } else { - MemoryMarshal.Write(destination, ref value); + MemoryMarshal.Write(destination, in value); } } @@ -267,10 +267,10 @@ public static bool TryWriteDoubleLittleEndian(Span destination, double val if (!BitConverter.IsLittleEndian) { long tmp = ReverseEndianness(BitConverter.DoubleToInt64Bits(value)); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -288,10 +288,10 @@ public static bool TryWriteHalfLittleEndian(Span destination, Half value) if (!BitConverter.IsLittleEndian) { short tmp = ReverseEndianness(BitConverter.HalfToInt16Bits(value)); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -304,10 +304,10 @@ public static bool TryWriteInt16LittleEndian(Span destination, short value if (!BitConverter.IsLittleEndian) { short tmp = ReverseEndianness(value); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -320,10 +320,10 @@ public static bool TryWriteInt32LittleEndian(Span destination, int value) if (!BitConverter.IsLittleEndian) { int tmp = ReverseEndianness(value); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -336,10 +336,10 @@ public static bool TryWriteInt64LittleEndian(Span destination, long value) if (!BitConverter.IsLittleEndian) { long tmp = ReverseEndianness(value); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -352,10 +352,10 @@ public static bool TryWriteInt128LittleEndian(Span destination, Int128 val if (!BitConverter.IsLittleEndian) { Int128 tmp = ReverseEndianness(value); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -368,10 +368,10 @@ public static bool TryWriteIntPtrLittleEndian(Span destination, nint value if (!BitConverter.IsLittleEndian) { nint tmp = ReverseEndianness(value); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -389,10 +389,10 @@ public static bool TryWriteSingleLittleEndian(Span destination, float valu if (!BitConverter.IsLittleEndian) { int tmp = ReverseEndianness(BitConverter.SingleToInt32Bits(value)); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -406,10 +406,10 @@ public static bool TryWriteUInt16LittleEndian(Span destination, ushort val if (!BitConverter.IsLittleEndian) { ushort tmp = ReverseEndianness(value); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -423,10 +423,10 @@ public static bool TryWriteUInt32LittleEndian(Span destination, uint value if (!BitConverter.IsLittleEndian) { uint tmp = ReverseEndianness(value); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -440,10 +440,10 @@ public static bool TryWriteUInt64LittleEndian(Span destination, ulong valu if (!BitConverter.IsLittleEndian) { ulong tmp = ReverseEndianness(value); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -457,10 +457,10 @@ public static bool TryWriteUInt128LittleEndian(Span destination, UInt128 v if (!BitConverter.IsLittleEndian) { UInt128 tmp = ReverseEndianness(value); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } /// @@ -474,10 +474,10 @@ public static bool TryWriteUIntPtrLittleEndian(Span destination, nuint val if (!BitConverter.IsLittleEndian) { nuint tmp = ReverseEndianness(value); - return MemoryMarshal.TryWrite(destination, ref tmp); + return MemoryMarshal.TryWrite(destination, in tmp); } - return MemoryMarshal.TryWrite(destination, ref value); + return MemoryMarshal.TryWrite(destination, in value); } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Guid.cs b/src/libraries/System.Private.CoreLib/src/System/Guid.cs index 276f1e20dc5af4..de618adf77ceb4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Guid.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Guid.cs @@ -851,13 +851,13 @@ public byte[] ToByteArray() var g = new byte[16]; if (BitConverter.IsLittleEndian) { - MemoryMarshal.TryWrite(g, ref Unsafe.AsRef(in this)); + MemoryMarshal.TryWrite(g, in this); } else { // slower path for BigEndian Guid guid = new Guid(AsBytes(this), false); - MemoryMarshal.TryWrite(g, ref Unsafe.AsRef(in guid)); + MemoryMarshal.TryWrite(g, in guid); } return g; } @@ -869,13 +869,13 @@ public byte[] ToByteArray(bool bigEndian) var g = new byte[16]; if (BitConverter.IsLittleEndian != bigEndian) { - MemoryMarshal.TryWrite(g, ref Unsafe.AsRef(in this)); + MemoryMarshal.TryWrite(g, in this); } else { // slower path for Reverse Guid guid = new Guid(AsBytes(this), bigEndian); - MemoryMarshal.TryWrite(g, ref Unsafe.AsRef(in guid)); + MemoryMarshal.TryWrite(g, in guid); } return g; } @@ -888,13 +888,13 @@ public bool TryWriteBytes(Span destination) if (BitConverter.IsLittleEndian) { - MemoryMarshal.TryWrite(destination, ref Unsafe.AsRef(in this)); + MemoryMarshal.TryWrite(destination, in this); } else { // slower path for BigEndian Guid guid = new Guid(AsBytes(this), false); - MemoryMarshal.TryWrite(destination, ref Unsafe.AsRef(in guid)); + MemoryMarshal.TryWrite(destination, in guid); } return true; } @@ -910,13 +910,13 @@ public bool TryWriteBytes(Span destination, bool bigEndian, out int bytesW if (BitConverter.IsLittleEndian != bigEndian) { - MemoryMarshal.TryWrite(destination, ref Unsafe.AsRef(in this)); + MemoryMarshal.TryWrite(destination, in this); } else { // slower path for Reverse Guid guid = new Guid(AsBytes(this), bigEndian); - MemoryMarshal.TryWrite(destination, ref Unsafe.AsRef(in guid)); + MemoryMarshal.TryWrite(destination, in guid); } bytesWritten = 16; return true; diff --git a/src/libraries/System.Private.CoreLib/src/System/Nullable.cs b/src/libraries/System.Private.CoreLib/src/System/Nullable.cs index 0766eca30a4dff..2eb6e5002968a2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Nullable.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Nullable.cs @@ -127,7 +127,7 @@ public static bool Equals(T? n1, T? n2) where T : struct /// called when the input reference points to a value with an actual location and not an "rvalue" (an expression that may appear on the right side but not left side of an assignment). That is, if this API is called and the input reference /// points to a value that is produced by the compiler as a defensive copy or a temporary copy, the behavior might not match the desired one. /// - public static ref readonly T GetValueRefOrDefaultRef(in T? nullable) + public static ref readonly T GetValueRefOrDefaultRef(ref readonly T? nullable) where T : struct { return ref nullable.value; diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs index a4efb431fb4339..3c9c5b88e9ece0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector.cs @@ -1025,11 +1025,11 @@ public static Vector LoadAligned(T* source) /// The type of () is not supported. [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector LoadUnsafe(ref T source) + public static Vector LoadUnsafe(ref readonly T source) { ThrowHelper.ThrowForUnsupportedNumericsVectorBaseType(); - ref byte address = ref Unsafe.As(ref source); - return Unsafe.ReadUnaligned>(ref address); + ref readonly byte address = ref Unsafe.As(ref Unsafe.AsRef(in source)); + return Unsafe.ReadUnaligned>(in address); } /// Loads a vector from the given source and element offset. @@ -1041,11 +1041,11 @@ public static Vector LoadUnsafe(ref T source) [Intrinsic] [CLSCompliant(false)] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector LoadUnsafe(ref T source, nuint elementOffset) + public static Vector LoadUnsafe(ref readonly T source, nuint elementOffset) { ThrowHelper.ThrowForUnsupportedNumericsVectorBaseType(); - source = ref Unsafe.Add(ref source, (nint)elementOffset); - return Unsafe.ReadUnaligned>(ref Unsafe.As(ref source)); + ref readonly byte address = ref Unsafe.As(ref Unsafe.Add(ref Unsafe.AsRef(in source), (nint)elementOffset)); + return Unsafe.ReadUnaligned>(in address); } /// Computes the maximum of two vectors on a per-element basis. diff --git a/src/libraries/System.Private.CoreLib/src/System/ReadOnlySpan.cs b/src/libraries/System.Private.CoreLib/src/System/ReadOnlySpan.cs index fecdfe7db790f9..056cda06faf955 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ReadOnlySpan.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ReadOnlySpan.cs @@ -113,7 +113,7 @@ public unsafe ReadOnlySpan(void* pointer, int length) /// Creates a new of length 1 around the specified reference. /// A reference to data. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ReadOnlySpan(in T reference) + public ReadOnlySpan(ref readonly T reference) { _reference = ref Unsafe.AsRef(in reference); _length = 1; diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBaseInvoker.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBaseInvoker.cs index 30e250d156d2b1..6f1667713ca7e5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBaseInvoker.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBaseInvoker.cs @@ -72,7 +72,7 @@ internal static void ThrowTargetParameterCountException() Debug.Assert(_argCount == 1); object? arg = parameters[0]; - ReadOnlySpan parametersSpan = new(arg); + var parametersSpan = new ReadOnlySpan(in arg); object? copyOfArg = null; Span copyOfArgs = new(ref copyOfArg); @@ -300,7 +300,7 @@ internal void InvokePropertySetter( bool copyBack = false; Span shouldCopyBack = new(ref copyBack, 1); // Not used for setters - CheckArguments(new ReadOnlySpan(parameter), copyOfArgs, shouldCopyBack, binder, culture, invokeAttr); + CheckArguments(new ReadOnlySpan(in parameter), copyOfArgs, shouldCopyBack, binder, culture, invokeAttr); if (_invokeFunc_ObjSpanArgs is not null) // Fast path check { diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/Unsafe.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/Unsafe.cs index 3affb74f3783ec..93cf27003b147a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/Unsafe.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/Unsafe.cs @@ -228,7 +228,7 @@ public static ref T AddByteOffset(ref T source, nuint byteOffset) // Mono:AreSame [NonVersionable] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool AreSame([AllowNull] ref T left, [AllowNull] ref T right) + public static bool AreSame([AllowNull] ref readonly T left, [AllowNull] ref readonly T right) { throw new PlatformNotSupportedException(); @@ -264,7 +264,7 @@ public static TTo BitCast(TFrom source) [NonVersionable] [CLSCompliant(false)] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Copy(void* destination, ref T source) + public static void Copy(void* destination, ref readonly T source) { throw new PlatformNotSupportedException(); @@ -321,7 +321,7 @@ public static void CopyBlock(void* destination, void* source, uint byteCount) [NonVersionable] [CLSCompliant(false)] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void CopyBlock(ref byte destination, ref byte source, uint byteCount) + public static void CopyBlock(ref byte destination, ref readonly byte source, uint byteCount) { throw new PlatformNotSupportedException(); @@ -360,7 +360,7 @@ public static void CopyBlockUnaligned(void* destination, void* source, uint byte [NonVersionable] [CLSCompliant(false)] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void CopyBlockUnaligned(ref byte destination, ref byte source, uint byteCount) + public static void CopyBlockUnaligned(ref byte destination, ref readonly byte source, uint byteCount) { throw new PlatformNotSupportedException(); @@ -385,7 +385,7 @@ public static void CopyBlockUnaligned(ref byte destination, ref byte source, uin // Mono:IsAddressGreaterThan [NonVersionable] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsAddressGreaterThan([AllowNull] ref T left, [AllowNull] ref T right) + public static bool IsAddressGreaterThan([AllowNull] ref readonly T left, [AllowNull] ref readonly T right) { throw new PlatformNotSupportedException(); @@ -408,7 +408,7 @@ public static bool IsAddressGreaterThan([AllowNull] ref T left, [AllowNull] r // Mono:IsAddressLessThan [NonVersionable] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsAddressLessThan([AllowNull] ref T left, [AllowNull] ref T right) + public static bool IsAddressLessThan([AllowNull] ref readonly T left, [AllowNull] ref readonly T right) { throw new PlatformNotSupportedException(); @@ -537,13 +537,13 @@ public static T ReadUnaligned(void* source) // Mono:ReadUnaligned [NonVersionable] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T ReadUnaligned(ref byte source) + public static T ReadUnaligned(ref readonly byte source) { #if CORECLR typeof(T).ToString(); // Type token used by the actual method body throw new PlatformNotSupportedException(); #else - return As(ref source); + return As(ref Unsafe.AsRef(in source)); #endif // ldarg.0 @@ -667,7 +667,7 @@ public static ref T AsRef(void* source) // Mono:AsRef [NonVersionable] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ref T AsRef(scoped in T source) + public static ref T AsRef(scoped ref readonly T source) { throw new PlatformNotSupportedException(); @@ -684,7 +684,7 @@ public static ref T AsRef(scoped in T source) // Mono:ByteOffset [NonVersionable] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static IntPtr ByteOffset([AllowNull] ref T origin, [AllowNull] ref T target) + public static IntPtr ByteOffset([AllowNull] ref readonly T origin, [AllowNull] ref readonly T target) { throw new PlatformNotSupportedException(); @@ -722,9 +722,9 @@ public static ref T NullRef() // AOT: IsNullRef [NonVersionable] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsNullRef(ref T source) + public static bool IsNullRef(ref readonly T source) { - return AsPointer(ref source) == null; + return AsPointer(ref Unsafe.AsRef(in source)) == null; // ldarg.0 // ldc.i4.0 diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs index 8e4f8fb6c13714..98dde70ae362db 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs @@ -130,7 +130,7 @@ public static int SizeOf() return SizeOfHelper(t, throwIfNotMarshalable: true); } - public static unsafe int QueryInterface(IntPtr pUnk, ref Guid iid, out IntPtr ppv) + public static unsafe int QueryInterface(IntPtr pUnk, in Guid iid, out IntPtr ppv) { ArgumentNullException.ThrowIfNull(pUnk); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.cs index 05251d7345bf42..2fc9946f03803b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.cs @@ -244,7 +244,7 @@ public static Span CreateSpan(scoped ref T reference, int length) => /// of the returned span will not be validated for safety, even by span-aware languages. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ReadOnlySpan CreateReadOnlySpan(scoped ref T reference, int length) => + public static ReadOnlySpan CreateReadOnlySpan(scoped ref readonly T reference, int length) => new ReadOnlySpan(ref Unsafe.AsRef(in reference), length); /// Creates a new read-only span for a null-terminated string. @@ -508,7 +508,7 @@ public static unsafe bool TryRead(ReadOnlySpan source, out T value) /// Writes a structure of type T into a span of bytes. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe void Write(Span destination, ref T value) + public static unsafe void Write(Span destination, in T value) where T : struct { if (RuntimeHelpers.IsReferenceOrContainsReferences()) @@ -527,7 +527,7 @@ public static unsafe void Write(Span destination, ref T value) /// /// If the span is too small to contain the type T, return false. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe bool TryWrite(Span destination, ref T value) + public static unsafe bool TryWrite(Span destination, in T value) where T : struct { if (RuntimeHelpers.IsReferenceOrContainsReferences()) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs index afc252563c0401..03091574967cb2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs @@ -1741,11 +1741,11 @@ public static unsafe Vector128 LoadAligned(T* source) /// The type of () is not supported. [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector128 LoadUnsafe(ref T source) + public static Vector128 LoadUnsafe(ref readonly T source) { ThrowHelper.ThrowForUnsupportedIntrinsicsVector128BaseType(); - ref byte address = ref Unsafe.As(ref source); - return Unsafe.ReadUnaligned>(ref address); + ref readonly byte address = ref Unsafe.As(ref Unsafe.AsRef(in source)); + return Unsafe.ReadUnaligned>(in address); } /// Loads a vector from the given source and element offset. @@ -1757,11 +1757,11 @@ public static Vector128 LoadUnsafe(ref T source) [Intrinsic] [CLSCompliant(false)] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector128 LoadUnsafe(ref T source, nuint elementOffset) + public static Vector128 LoadUnsafe(ref readonly T source, nuint elementOffset) { ThrowHelper.ThrowForUnsupportedIntrinsicsVector128BaseType(); - source = ref Unsafe.Add(ref source, (nint)elementOffset); - return Unsafe.ReadUnaligned>(ref Unsafe.As(ref source)); + ref readonly byte address = ref Unsafe.As(ref Unsafe.Add(ref Unsafe.AsRef(in source), (nint)elementOffset)); + return Unsafe.ReadUnaligned>(in address); } /// Loads a vector from the given source and reinterprets it as . diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs index 758d0291af49e6..9c3360a5e617ee 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs @@ -1715,11 +1715,11 @@ public static Vector256 LoadAligned(T* source) /// The type of () is not supported. [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector256 LoadUnsafe(ref T source) + public static Vector256 LoadUnsafe(ref readonly T source) { ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType(); - ref byte address = ref Unsafe.As(ref source); - return Unsafe.ReadUnaligned>(ref address); + ref readonly byte address = ref Unsafe.As(ref Unsafe.AsRef(in source)); + return Unsafe.ReadUnaligned>(in address); } /// Loads a vector from the given source and element offset. @@ -1731,11 +1731,11 @@ public static Vector256 LoadUnsafe(ref T source) [Intrinsic] [CLSCompliant(false)] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector256 LoadUnsafe(ref T source, nuint elementOffset) + public static Vector256 LoadUnsafe(ref readonly T source, nuint elementOffset) { ThrowHelper.ThrowForUnsupportedIntrinsicsVector256BaseType(); - source = ref Unsafe.Add(ref source, (nint)elementOffset); - return Unsafe.ReadUnaligned>(ref Unsafe.As(ref source)); + ref readonly byte address = ref Unsafe.As(ref Unsafe.Add(ref Unsafe.AsRef(in source), (nint)elementOffset)); + return Unsafe.ReadUnaligned>(in address); } /// Loads a vector from the given source and reinterprets it as . diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs index 5b740db4300982..f95c2d34c3c5f1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs @@ -1768,11 +1768,11 @@ public static Vector512 LoadAligned(T* source) /// The type of () is not supported. [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector512 LoadUnsafe(ref T source) + public static Vector512 LoadUnsafe(ref readonly T source) { ThrowHelper.ThrowForUnsupportedIntrinsicsVector512BaseType(); - ref byte address = ref Unsafe.As(ref source); - return Unsafe.ReadUnaligned>(ref address); + ref readonly byte address = ref Unsafe.As(ref Unsafe.AsRef(in source)); + return Unsafe.ReadUnaligned>(in address); } /// Loads a vector from the given source and element offset. @@ -1784,11 +1784,11 @@ public static Vector512 LoadUnsafe(ref T source) [Intrinsic] [CLSCompliant(false)] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector512 LoadUnsafe(ref T source, nuint elementOffset) + public static Vector512 LoadUnsafe(ref readonly T source, nuint elementOffset) { ThrowHelper.ThrowForUnsupportedIntrinsicsVector512BaseType(); - source = ref Unsafe.Add(ref source, (nint)elementOffset); - return Unsafe.ReadUnaligned>(ref Unsafe.As(ref source)); + ref readonly byte address = ref Unsafe.As(ref Unsafe.Add(ref Unsafe.AsRef(in source), (nint)elementOffset)); + return Unsafe.ReadUnaligned>(in address); } /// Loads a vector from the given source and reinterprets it as . diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs index 11fd7d7591a8d2..4f314511bc9487 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs @@ -1524,11 +1524,11 @@ public static unsafe Vector64 LoadAligned(T* source) /// The type of () is not supported. [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector64 LoadUnsafe(ref T source) + public static Vector64 LoadUnsafe(ref readonly T source) { ThrowHelper.ThrowForUnsupportedIntrinsicsVector64BaseType(); - ref byte address = ref Unsafe.As(ref source); - return Unsafe.ReadUnaligned>(ref address); + ref readonly byte address = ref Unsafe.As(ref Unsafe.AsRef(in source)); + return Unsafe.ReadUnaligned>(in address); } /// Loads a vector from the given source and element offset. @@ -1540,11 +1540,11 @@ public static Vector64 LoadUnsafe(ref T source) [Intrinsic] [CLSCompliant(false)] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector64 LoadUnsafe(ref T source, nuint elementOffset) + public static Vector64 LoadUnsafe(ref readonly T source, nuint elementOffset) { ThrowHelper.ThrowForUnsupportedIntrinsicsVector64BaseType(); - source = ref Unsafe.Add(ref source, (nint)elementOffset); - return Unsafe.ReadUnaligned>(ref Unsafe.As(ref source)); + ref readonly byte address = ref Unsafe.As(ref Unsafe.Add(ref Unsafe.AsRef(in source), (nint)elementOffset)); + return Unsafe.ReadUnaligned>(in address); } /// Computes the maximum of two vectors on a per-element basis. diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Interlocked.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Interlocked.cs index f40564b6746e63..465d7d70a35d15 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Interlocked.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Interlocked.cs @@ -228,8 +228,8 @@ public static ulong Add(ref ulong location1, ulong value) => /// The loaded value. [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] - public static ulong Read(ref ulong location) => - CompareExchange(ref location, 0, 0); + public static ulong Read(ref readonly ulong location) => + CompareExchange(ref Unsafe.AsRef(in location), 0, 0); #endregion #region And diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Volatile.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Volatile.cs index bae9163e40cff9..284b582a78f148 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Volatile.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Volatile.cs @@ -18,8 +18,8 @@ private struct VolatileBoolean { public volatile bool Value; } [Intrinsic] [NonVersionable] - public static bool Read(ref bool location) => - Unsafe.As(ref location).Value; + public static bool Read(ref readonly bool location) => + Unsafe.As(ref Unsafe.AsRef(in location)).Value; [Intrinsic] [NonVersionable] @@ -32,8 +32,8 @@ private struct VolatileByte { public volatile byte Value; } [Intrinsic] [NonVersionable] - public static byte Read(ref byte location) => - Unsafe.As(ref location).Value; + public static byte Read(ref readonly byte location) => + Unsafe.As(ref Unsafe.AsRef(in location)).Value; [Intrinsic] [NonVersionable] @@ -44,9 +44,9 @@ public static void Write(ref byte location, byte value) => #region Double [Intrinsic] [NonVersionable] - public static double Read(ref double location) + public static double Read(ref readonly double location) { - long result = Read(ref Unsafe.As(ref location)); + long result = Read(ref Unsafe.As(ref Unsafe.AsRef(in location))); return BitConverter.Int64BitsToDouble(result); } @@ -61,8 +61,8 @@ private struct VolatileInt16 { public volatile short Value; } [Intrinsic] [NonVersionable] - public static short Read(ref short location) => - Unsafe.As(ref location).Value; + public static short Read(ref readonly short location) => + Unsafe.As(ref Unsafe.AsRef(in location)).Value; [Intrinsic] [NonVersionable] @@ -75,8 +75,8 @@ private struct VolatileInt32 { public volatile int Value; } [Intrinsic] [NonVersionable] - public static int Read(ref int location) => - Unsafe.As(ref location).Value; + public static int Read(ref readonly int location) => + Unsafe.As(ref Unsafe.AsRef(in location)).Value; [Intrinsic] [NonVersionable] @@ -87,12 +87,12 @@ public static void Write(ref int location, int value) => #region Int64 [Intrinsic] [NonVersionable] - public static long Read(ref long location) => + public static long Read(ref readonly long location) => #if TARGET_64BIT - (long)Unsafe.As(ref location).Value; + (long)Unsafe.As(ref Unsafe.AsRef(in location)).Value; #else // On 32-bit machines, we use Interlocked, since an ordinary volatile read would not be atomic. - Interlocked.CompareExchange(ref location, 0, 0); + Interlocked.CompareExchange(ref Unsafe.AsRef(in location), 0, 0); #endif [Intrinsic] @@ -111,8 +111,8 @@ private struct VolatileIntPtr { public volatile IntPtr Value; } [Intrinsic] [NonVersionable] - public static IntPtr Read(ref IntPtr location) => - Unsafe.As(ref location).Value; + public static IntPtr Read(ref readonly IntPtr location) => + Unsafe.As(ref Unsafe.AsRef(in location)).Value; [Intrinsic] [NonVersionable] @@ -126,8 +126,8 @@ private struct VolatileSByte { public volatile sbyte Value; } [CLSCompliant(false)] [Intrinsic] [NonVersionable] - public static sbyte Read(ref sbyte location) => - Unsafe.As(ref location).Value; + public static sbyte Read(ref readonly sbyte location) => + Unsafe.As(ref Unsafe.AsRef(in location)).Value; [CLSCompliant(false)] [Intrinsic] @@ -141,8 +141,8 @@ private struct VolatileSingle { public volatile float Value; } [Intrinsic] [NonVersionable] - public static float Read(ref float location) => - Unsafe.As(ref location).Value; + public static float Read(ref readonly float location) => + Unsafe.As(ref Unsafe.AsRef(in location)).Value; [Intrinsic] [NonVersionable] @@ -156,8 +156,8 @@ private struct VolatileUInt16 { public volatile ushort Value; } [CLSCompliant(false)] [Intrinsic] [NonVersionable] - public static ushort Read(ref ushort location) => - Unsafe.As(ref location).Value; + public static ushort Read(ref readonly ushort location) => + Unsafe.As(ref Unsafe.AsRef(in location)).Value; [CLSCompliant(false)] [Intrinsic] @@ -172,8 +172,8 @@ private struct VolatileUInt32 { public volatile uint Value; } [CLSCompliant(false)] [Intrinsic] [NonVersionable] - public static uint Read(ref uint location) => - Unsafe.As(ref location).Value; + public static uint Read(ref readonly uint location) => + Unsafe.As(ref Unsafe.AsRef(in location)).Value; [CLSCompliant(false)] [Intrinsic] @@ -186,8 +186,8 @@ public static void Write(ref uint location, uint value) => [CLSCompliant(false)] [Intrinsic] [NonVersionable] - public static ulong Read(ref ulong location) => - (ulong)Read(ref Unsafe.As(ref location)); + public static ulong Read(ref readonly ulong location) => + (ulong)Read(ref Unsafe.As(ref Unsafe.AsRef(in location))); [CLSCompliant(false)] [Intrinsic] @@ -202,8 +202,8 @@ private struct VolatileUIntPtr { public volatile UIntPtr Value; } [CLSCompliant(false)] [Intrinsic] [NonVersionable] - public static UIntPtr Read(ref UIntPtr location) => - Unsafe.As(ref location).Value; + public static UIntPtr Read(ref readonly UIntPtr location) => + Unsafe.As(ref Unsafe.AsRef(in location)).Value; [CLSCompliant(false)] [Intrinsic] @@ -218,8 +218,8 @@ private struct VolatileObject { public volatile object? Value; } [Intrinsic] [NonVersionable] [return: NotNullIfNotNull(nameof(location))] - public static T Read([NotNullIfNotNull(nameof(location))] ref T location) where T : class? => - Unsafe.As(Unsafe.As(ref location).Value); + public static T Read([NotNullIfNotNull(nameof(location))] ref readonly T location) where T : class? => + Unsafe.As(Unsafe.As(ref Unsafe.AsRef(in location)).Value); [Intrinsic] [NonVersionable] diff --git a/src/libraries/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs b/src/libraries/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs index b07ef0c72d13e0..13488161781df5 100644 --- a/src/libraries/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs +++ b/src/libraries/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs @@ -481,7 +481,7 @@ public static void InAsRef() { int[] a = new int[] { 0x123, 0x234, 0x345, 0x456 }; - ref int r = ref Unsafe.AsRef(a[0]); + ref int r = ref Unsafe.AsRef(in a[0]); Assert.Equal(0x123, r); r = 0x42; diff --git a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs index 0d80a901d93ad0..8fe3d526ab6e96 100644 --- a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs +++ b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs @@ -1104,7 +1104,7 @@ public static void PtrToStructure(System.IntPtr ptr, object structure) { } public static object? PtrToStructure(System.IntPtr ptr, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicConstructors| System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type structureType) { throw null; } public static T? PtrToStructure<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)]T>(System.IntPtr ptr) { throw null; } public static void PtrToStructure(System.IntPtr ptr, [System.Diagnostics.CodeAnalysis.DisallowNullAttribute] T structure) { } - public static int QueryInterface(System.IntPtr pUnk, ref System.Guid iid, out System.IntPtr ppv) { throw null; } + public static int QueryInterface(System.IntPtr pUnk, in System.Guid iid, out System.IntPtr ppv) { throw null; } public static byte ReadByte(System.IntPtr ptr) { throw null; } public static byte ReadByte(System.IntPtr ptr, int ofs) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Marshalling code for the object might not be available")] diff --git a/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/ComInterfaceMarshaller.cs b/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/ComInterfaceMarshaller.cs index ec7dd75db1ac99..39f443673fcc71 100644 --- a/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/ComInterfaceMarshaller.cs +++ b/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/ComInterfaceMarshaller.cs @@ -76,11 +76,10 @@ public static void Free(void* unmanaged) // If the managed type isn't a GeneratedComInterface-attributed type, we'll marshal to an IUnknown*. return (void*)unknown; } - Guid iid = TargetInterfaceIID.Value; - if (Marshal.QueryInterface(unknown, ref iid, out nint interfacePointer) != 0) + if (Marshal.QueryInterface(unknown, in Nullable.GetValueRefOrDefaultRef(in TargetInterfaceIID), out nint interfacePointer) != 0) { Marshal.Release(unknown); - throw new InvalidCastException($"Unable to cast the provided managed object to a COM interface with ID '{iid:B}'"); + throw new InvalidCastException($"Unable to cast the provided managed object to a COM interface with ID '{TargetInterfaceIID.GetValueOrDefault():B}'"); } Marshal.Release(unknown); return (void*)interfacePointer; diff --git a/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/FreeThreadedStrategy.cs b/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/FreeThreadedStrategy.cs index 054bf57f14a022..921edb082fd96c 100644 --- a/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/FreeThreadedStrategy.cs +++ b/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/FreeThreadedStrategy.cs @@ -18,7 +18,7 @@ internal sealed unsafe class FreeThreadedStrategy : IIUnknownStrategy unsafe int IIUnknownStrategy.QueryInterface(void* thisPtr, in Guid handle, out void* ppObj) { - int hr = Marshal.QueryInterface((nint)thisPtr, ref Unsafe.AsRef(in handle), out nint ppv); + int hr = Marshal.QueryInterface((nint)thisPtr, in handle, out nint ppv); if (hr < 0) { ppObj = null; diff --git a/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/IIUnknownStrategy.cs b/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/IIUnknownStrategy.cs index 7781d12f03bafc..771b88b04e7f4d 100644 --- a/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/IIUnknownStrategy.cs +++ b/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/IIUnknownStrategy.cs @@ -32,7 +32,7 @@ public unsafe interface IIUnknownStrategy /// The IID (Interface ID) to query for. /// The resulting interface. /// Returns an HRESULT represents the success of the operation. - /// + /// public int QueryInterface(void* instancePtr, in Guid iid, out void* ppObj); /// diff --git a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/GeneratedComClassTests.cs b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/GeneratedComClassTests.cs index b8dbf345e5eb76..a1e34461f4a118 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/GeneratedComClassTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/GeneratedComClassTests.cs @@ -47,7 +47,7 @@ public void ComInstanceProvidesInterfaceForDirectlyImplementedComInterface() nint ptr = wrappers.GetOrCreateComInterfaceForObject(obj, CreateComInterfaceFlags.None); Assert.NotEqual(0, ptr); var iid = typeof(IGetAndSetInt).GUID; - Assert.Equal(0, Marshal.QueryInterface(ptr, ref iid, out nint iComInterface)); + Assert.Equal(0, Marshal.QueryInterface(ptr, in iid, out nint iComInterface)); Assert.NotEqual(0, iComInterface); Marshal.Release(iComInterface); Marshal.Release(ptr); @@ -61,7 +61,7 @@ public void ComInstanceProvidesInterfaceForIndirectlyImplementedComInterface() nint ptr = wrappers.GetOrCreateComInterfaceForObject(obj, CreateComInterfaceFlags.None); Assert.NotEqual(0, ptr); var iid = typeof(IGetAndSetInt).GUID; - Assert.Equal(0, Marshal.QueryInterface(ptr, ref iid, out nint iComInterface)); + Assert.Equal(0, Marshal.QueryInterface(ptr, in iid, out nint iComInterface)); Assert.NotEqual(0, iComInterface); Marshal.Release(iComInterface); Marshal.Release(ptr); diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/QueryInterfaceTests.Windows.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/QueryInterfaceTests.Windows.cs index 12f1a69a4e9121..a8e4edc7be601e 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/QueryInterfaceTests.Windows.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/QueryInterfaceTests.Windows.cs @@ -47,7 +47,7 @@ public void QueryInterface_ValidComObjectInterface_Success(object o, string iidS try { Guid guid = new Guid(iidString); - Assert.Equal(0, Marshal.QueryInterface(ptr, ref guid, out IntPtr ppv)); + Assert.Equal(0, Marshal.QueryInterface(ptr, in guid, out IntPtr ppv)); Assert.NotEqual(IntPtr.Zero, ppv); try { @@ -103,7 +103,7 @@ public void QueryInterface_NoSuchComObjectInterface_Success(object o, string iid try { Guid iid = new Guid(iidString); - Assert.Equal(E_NOINTERFACE, Marshal.QueryInterface(ptr, ref iid, out IntPtr ppv)); + Assert.Equal(E_NOINTERFACE, Marshal.QueryInterface(ptr, in iid, out IntPtr ppv)); Assert.Equal(IntPtr.Zero, ppv); Assert.Equal(new Guid(iidString), iid); } diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/QueryInterfaceTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/QueryInterfaceTests.cs index 41838ed5b956a5..f662c02a76c75f 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/QueryInterfaceTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/Marshal/QueryInterfaceTests.cs @@ -30,7 +30,7 @@ public void QueryInterface_ValidInterface_Success(object o, string iidString) try { Guid guid = new Guid(iidString); - Assert.Equal(0, Marshal.QueryInterface(ptr, ref guid, out IntPtr ppv)); + Assert.Equal(0, Marshal.QueryInterface(ptr, in guid, out IntPtr ppv)); Assert.NotEqual(IntPtr.Zero, ppv); try { @@ -64,7 +64,7 @@ public void QueryInterface_NoSuchInterface_Success(object o, string iidString) try { Guid iid = new Guid(iidString); - Assert.Equal(E_NOINTERFACE, Marshal.QueryInterface(ptr, ref iid, out IntPtr ppv)); + Assert.Equal(E_NOINTERFACE, Marshal.QueryInterface(ptr, in iid, out IntPtr ppv)); Assert.Equal(IntPtr.Zero, ppv); Assert.Equal(new Guid(iidString), iid); } @@ -78,7 +78,7 @@ public void QueryInterface_NoSuchInterface_Success(object o, string iidString) public void QueryInterface_ZeroPointer_ThrowsArgumentNullException() { Guid iid = Guid.Empty; - AssertExtensions.Throws("pUnk", () => Marshal.QueryInterface(IntPtr.Zero, ref iid, out IntPtr ppv)); + AssertExtensions.Throws("pUnk", () => Marshal.QueryInterface(IntPtr.Zero, in iid, out IntPtr ppv)); } } } diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/Arrays.cs b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/Arrays.cs index 3ee3458f494eaf..dea37b2a7e27df 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/Arrays.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/Arrays.cs @@ -242,7 +242,7 @@ public static void ReverseStringsReplace(ushort*** strArray, int* numValues) const int NumBytesInLong = sizeof(long); byte* bytes = (byte*)Marshal.AllocCoTaskMem(NumBytesInLong); - MemoryMarshal.Write(new Span(bytes, NumBytesInLong), ref l); + MemoryMarshal.Write(new Span(bytes, NumBytesInLong), in l); return bytes; } diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/ComInterfaces.cs b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/ComInterfaces.cs index 651f02ba66cc1a..815ed2ce6f95e8 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/ComInterfaces.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/NativeExports/ComInterfaces.cs @@ -100,7 +100,7 @@ static ComInterfaceEntry* MyObjectComInterfaceEntries } protected override object CreateObject(nint ptr, CreateObjectFlags flags) { - int hr = Marshal.QueryInterface(ptr, ref IComInterface1.IID, out IntPtr IComInterfaceImpl); + int hr = Marshal.QueryInterface(ptr, in IComInterface1.IID, out IntPtr IComInterfaceImpl); if (hr != 0) { return null; diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index 760d934c288409..01cdb46a9de57b 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -182,9 +182,9 @@ public static void CopyTo(this System.Runtime.Intrinsics.Vector128 vector, [System.CLSCompliantAttribute(false)] public static unsafe System.Runtime.Intrinsics.Vector128 LoadAlignedNonTemporal(T* source) { throw null; } #pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type ('T') - public static System.Runtime.Intrinsics.Vector128 LoadUnsafe(ref T source) { throw null; } + public static System.Runtime.Intrinsics.Vector128 LoadUnsafe(ref readonly T source) { throw null; } [System.CLSCompliantAttribute(false)] - public static System.Runtime.Intrinsics.Vector128 LoadUnsafe(ref T source, nuint elementOffset) { throw null; } + public static System.Runtime.Intrinsics.Vector128 LoadUnsafe(ref readonly T source, nuint elementOffset) { throw null; } public static System.Runtime.Intrinsics.Vector128 Max(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 Min(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } public static System.Runtime.Intrinsics.Vector128 Multiply(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right) { throw null; } @@ -509,9 +509,9 @@ public static void CopyTo(this System.Runtime.Intrinsics.Vector256 vector, [System.CLSCompliantAttribute(false)] public static unsafe System.Runtime.Intrinsics.Vector256 LoadAlignedNonTemporal(T* source) { throw null; } #pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type ('T') - public static System.Runtime.Intrinsics.Vector256 LoadUnsafe(ref T source) { throw null; } + public static System.Runtime.Intrinsics.Vector256 LoadUnsafe(ref readonly T source) { throw null; } [System.CLSCompliantAttribute(false)] - public static System.Runtime.Intrinsics.Vector256 LoadUnsafe(ref T source, nuint elementOffset) { throw null; } + public static System.Runtime.Intrinsics.Vector256 LoadUnsafe(ref readonly T source, nuint elementOffset) { throw null; } public static System.Runtime.Intrinsics.Vector256 Max(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right) { throw null; } public static System.Runtime.Intrinsics.Vector256 Min(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right) { throw null; } public static System.Runtime.Intrinsics.Vector256 Multiply(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right) { throw null; } @@ -836,9 +836,9 @@ public static void CopyTo(this System.Runtime.Intrinsics.Vector512 vector, [System.CLSCompliantAttribute(false)] public static unsafe System.Runtime.Intrinsics.Vector512 LoadAlignedNonTemporal(T* source) { throw null; } #pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type ('T') - public static System.Runtime.Intrinsics.Vector512 LoadUnsafe(ref T source) { throw null; } + public static System.Runtime.Intrinsics.Vector512 LoadUnsafe(ref readonly T source) { throw null; } [System.CLSCompliantAttribute(false)] - public static System.Runtime.Intrinsics.Vector512 LoadUnsafe(ref T source, nuint elementOffset) { throw null; } + public static System.Runtime.Intrinsics.Vector512 LoadUnsafe(ref readonly T source, nuint elementOffset) { throw null; } public static System.Runtime.Intrinsics.Vector512 Max(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 Min(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 Multiply(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } @@ -1135,9 +1135,9 @@ public static void CopyTo(this System.Runtime.Intrinsics.Vector64 vector, [System.CLSCompliantAttribute(false)] public static unsafe System.Runtime.Intrinsics.Vector64 LoadAlignedNonTemporal(T* source) { throw null; } #pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type ('T') - public static System.Runtime.Intrinsics.Vector64 LoadUnsafe(ref T source) { throw null; } + public static System.Runtime.Intrinsics.Vector64 LoadUnsafe(ref readonly T source) { throw null; } [System.CLSCompliantAttribute(false)] - public static System.Runtime.Intrinsics.Vector64 LoadUnsafe(ref T source, nuint elementOffset) { throw null; } + public static System.Runtime.Intrinsics.Vector64 LoadUnsafe(ref readonly T source, nuint elementOffset) { throw null; } public static System.Runtime.Intrinsics.Vector64 Max(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 Min(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } public static System.Runtime.Intrinsics.Vector64 Multiply(System.Runtime.Intrinsics.Vector64 left, System.Runtime.Intrinsics.Vector64 right) { throw null; } diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 03b8b7f4a55ed8..97ef4d74a44507 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -4440,7 +4440,7 @@ public static partial class Nullable public static int Compare(T? n1, T? n2) where T : struct { throw null; } public static bool Equals(T? n1, T? n2) where T : struct { throw null; } public static System.Type? GetUnderlyingType(System.Type nullableType) { throw null; } - public static ref readonly T GetValueRefOrDefaultRef(in T? nullable) where T : struct { throw null; } + public static ref readonly T GetValueRefOrDefaultRef(ref readonly T? nullable) where T : struct { throw null; } } public partial struct Nullable where T : struct { @@ -4691,7 +4691,7 @@ public readonly ref partial struct ReadOnlySpan public unsafe ReadOnlySpan(void* pointer, int length) { throw null; } public ReadOnlySpan(T[]? array) { throw null; } public ReadOnlySpan(T[]? array, int start, int length) { throw null; } - public ReadOnlySpan(in T reference) { throw null; } + public ReadOnlySpan(ref readonly T reference) { throw null; } public static System.ReadOnlySpan Empty { get { throw null; } } public bool IsEmpty { get { throw null; } } public ref readonly T this[int index] { get { throw null; } } @@ -13212,27 +13212,27 @@ public static partial class Unsafe public static ref T Add(ref T source, System.IntPtr elementOffset) { throw null; } [System.CLSCompliantAttribute(false)] public static ref T Add(ref T source, nuint elementOffset) { throw null; } - public static bool AreSame([System.Diagnostics.CodeAnalysis.AllowNull] ref T left, [System.Diagnostics.CodeAnalysis.AllowNull] ref T right) { throw null; } + public static bool AreSame([System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T left, [System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T right) { throw null; } [System.CLSCompliantAttribute(false)] public unsafe static void* AsPointer(ref T value) { throw null; } [System.CLSCompliantAttribute(false)] public unsafe static ref T AsRef(void* source) { throw null; } - public static ref T AsRef(scoped in T source) { throw null; } + public static ref T AsRef(scoped ref readonly T source) { throw null; } [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("o")] public static T? As(object? o) where T : class? { throw null; } public static ref TTo As(ref TFrom source) { throw null; } public static TTo BitCast(TFrom source) where TFrom : struct where TTo : struct { throw null; } - public static System.IntPtr ByteOffset([System.Diagnostics.CodeAnalysis.AllowNull] ref T origin, [System.Diagnostics.CodeAnalysis.AllowNull] ref T target) { throw null; } + public static System.IntPtr ByteOffset([System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T origin, [System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T target) { throw null; } [System.CLSCompliantAttribute(false)] - public static void CopyBlock(ref byte destination, ref byte source, uint byteCount) { } + public static void CopyBlock(ref byte destination, ref readonly byte source, uint byteCount) { } [System.CLSCompliantAttribute(false)] public unsafe static void CopyBlock(void* destination, void* source, uint byteCount) { } [System.CLSCompliantAttribute(false)] - public static void CopyBlockUnaligned(ref byte destination, ref byte source, uint byteCount) { } + public static void CopyBlockUnaligned(ref byte destination, ref readonly byte source, uint byteCount) { } [System.CLSCompliantAttribute(false)] public unsafe static void CopyBlockUnaligned(void* destination, void* source, uint byteCount) { } [System.CLSCompliantAttribute(false)] - public unsafe static void Copy(void* destination, ref T source) { } + public unsafe static void Copy(void* destination, ref readonly T source) { } [System.CLSCompliantAttribute(false)] public unsafe static void Copy(ref T destination, void* source) { } [System.CLSCompliantAttribute(false)] @@ -13243,11 +13243,11 @@ public unsafe static void InitBlock(void* startAddress, byte value, uint byteCou public static void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount) { } [System.CLSCompliantAttribute(false)] public unsafe static void InitBlockUnaligned(void* startAddress, byte value, uint byteCount) { } - public static bool IsAddressGreaterThan([System.Diagnostics.CodeAnalysis.AllowNull] ref T left, [System.Diagnostics.CodeAnalysis.AllowNull] ref T right) { throw null; } - public static bool IsAddressLessThan([System.Diagnostics.CodeAnalysis.AllowNull] ref T left, [System.Diagnostics.CodeAnalysis.AllowNull] ref T right) { throw null; } - public static bool IsNullRef(ref T source) { throw null; } + public static bool IsAddressGreaterThan([System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T left, [System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T right) { throw null; } + public static bool IsAddressLessThan([System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T left, [System.Diagnostics.CodeAnalysis.AllowNull] ref readonly T right) { throw null; } + public static bool IsNullRef(ref readonly T source) { throw null; } public static ref T NullRef() { throw null; } - public static T ReadUnaligned(ref byte source) { throw null; } + public static T ReadUnaligned(ref readonly byte source) { throw null; } [System.CLSCompliantAttribute(false)] public unsafe static T ReadUnaligned(void* source) { throw null; } [System.CLSCompliantAttribute(false)] diff --git a/src/libraries/System.Runtime/tests/System/NullableTests.cs b/src/libraries/System.Runtime/tests/System/NullableTests.cs index b130ba49b433c8..5e6f268915cca4 100644 --- a/src/libraries/System.Runtime/tests/System/NullableTests.cs +++ b/src/libraries/System.Runtime/tests/System/NullableTests.cs @@ -101,11 +101,11 @@ static void Test(T before, T after) where T : struct { T? nullable = before; - ref readonly T reference = ref Nullable.GetValueRefOrDefaultRef(nullable); + ref readonly T reference = ref Nullable.GetValueRefOrDefaultRef(in nullable); Assert.Equal(before, nullable!.Value); - Unsafe.AsRef(reference) = after; + Unsafe.AsRef(in reference) = after; Assert.Equal(after, nullable.Value); } @@ -124,7 +124,7 @@ static void Test() where T : struct { T? nullable = null; - ref readonly T reference = ref Nullable.GetValueRefOrDefaultRef(nullable); + ref readonly T reference = ref Nullable.GetValueRefOrDefaultRef(in nullable); Assert.Equal(nullable!.GetValueOrDefault(), reference); } @@ -143,9 +143,9 @@ static void Test(T after) where T : struct { T? nullable = null; - ref readonly T reference = ref Nullable.GetValueRefOrDefaultRef(nullable); + ref readonly T reference = ref Nullable.GetValueRefOrDefaultRef(in nullable); - Unsafe.AsRef(reference) = after; + Unsafe.AsRef(in reference) = after; Assert.Equal(after, nullable.GetValueOrDefault()); // GetValueOrDefault() unconditionally returns the field Assert.False(nullable.HasValue); diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/UnixExportProvider.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/UnixExportProvider.cs index f569435e605c61..d46676750e99ef 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/UnixExportProvider.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/UnixExportProvider.cs @@ -191,7 +191,7 @@ private void BuildBags( byte[] attrBytes = new byte[6]; attrBytes[0] = (byte)UniversalTagNumber.OctetString; attrBytes[1] = sizeof(int); - MemoryMarshal.Write(attrBytes.AsSpan(2), ref keyIdx); + MemoryMarshal.Write(attrBytes.AsSpan(2), in keyIdx); AttributeAsn attribute = new AttributeAsn { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.MetadataDb.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.MetadataDb.cs index 3df7184df65d76..afdbf4bd0b9b26 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.MetadataDb.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.MetadataDb.cs @@ -6,6 +6,10 @@ using System.Runtime.InteropServices; using System.Threading; +// We need to target netstandard2.0, so keep using ref for MemoryMarshal.Write +// CS9191: The 'ref' modifier for argument 2 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead. +#pragma warning disable CS9191 + namespace System.Text.Json { public sealed partial class JsonDocument diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.StackRowStack.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.StackRowStack.cs index 3288e954fad2e3..83b7b634913d27 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.StackRowStack.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.StackRowStack.cs @@ -5,6 +5,10 @@ using System.Diagnostics; using System.Runtime.InteropServices; +// We need to target netstandard2.0, so keep using ref for MemoryMarshal.Write +// CS9191: The 'ref' modifier for argument 2 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead. +#pragma warning disable CS9191 + namespace System.Text.Json { public sealed partial class JsonDocument diff --git a/src/libraries/System.Threading/ref/System.Threading.cs b/src/libraries/System.Threading/ref/System.Threading.cs index d837e35ad99890..765875597415b2 100644 --- a/src/libraries/System.Threading/ref/System.Threading.cs +++ b/src/libraries/System.Threading/ref/System.Threading.cs @@ -271,9 +271,9 @@ public static void MemoryBarrierProcessWide() { } public static uint Or(ref uint location1, uint value) { throw null; } [System.CLSCompliantAttribute(false)] public static ulong Or(ref ulong location1, ulong value) { throw null; } - public static long Read(ref long location) { throw null; } + public static long Read(ref readonly long location) { throw null; } [System.CLSCompliantAttribute(false)] - public static ulong Read(ref ulong location) { throw null; } + public static ulong Read(ref readonly ulong location) { throw null; } } public static partial class LazyInitializer { @@ -511,26 +511,27 @@ protected virtual void Dispose(bool disposing) { } } public static partial class Volatile { - public static bool Read(ref bool location) { throw null; } - public static byte Read(ref byte location) { throw null; } - public static double Read(ref double location) { throw null; } - public static short Read(ref short location) { throw null; } - public static int Read(ref int location) { throw null; } - public static long Read(ref long location) { throw null; } - public static System.IntPtr Read(ref System.IntPtr location) { throw null; } + public static bool Read(ref readonly bool location) { throw null; } + public static byte Read(ref readonly byte location) { throw null; } + public static double Read(ref readonly double location) { throw null; } + public static short Read(ref readonly short location) { throw null; } + public static int Read(ref readonly int location) { throw null; } + public static long Read(ref readonly long location) { throw null; } + public static System.IntPtr Read(ref readonly System.IntPtr location) { throw null; } [System.CLSCompliantAttribute(false)] - public static sbyte Read(ref sbyte location) { throw null; } - public static float Read(ref float location) { throw null; } + public static sbyte Read(ref readonly sbyte location) { throw null; } + public static float Read(ref readonly float location) { throw null; } [System.CLSCompliantAttribute(false)] - public static ushort Read(ref ushort location) { throw null; } + public static ushort Read(ref readonly ushort location) { throw null; } [System.CLSCompliantAttribute(false)] - public static uint Read(ref uint location) { throw null; } + public static uint Read(ref readonly uint location) { throw null; } [System.CLSCompliantAttribute(false)] - public static ulong Read(ref ulong location) { throw null; } + public static ulong Read(ref readonly ulong location) { throw null; } [System.CLSCompliantAttribute(false)] - public static System.UIntPtr Read(ref System.UIntPtr location) { throw null; } + public static System.UIntPtr Read(ref readonly System.UIntPtr location) { throw null; } [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("location")] - public static T Read([System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("location")] ref T location) where T : class? { throw null; } + public static T Read([System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("location")] ref readonly T location) where T : class? { throw null; } + public static void Write(ref bool location, bool value) { } public static void Write(ref byte location, byte value) { } public static void Write(ref double location, double value) { } diff --git a/src/libraries/System.Transactions.Local/src/System/Transactions/TransactionInterop.cs b/src/libraries/System.Transactions.Local/src/System/Transactions/TransactionInterop.cs index 3c5ecb5da0686f..67b1343cf52d4e 100644 --- a/src/libraries/System.Transactions.Local/src/System/Transactions/TransactionInterop.cs +++ b/src/libraries/System.Transactions.Local/src/System/Transactions/TransactionInterop.cs @@ -442,8 +442,7 @@ internal static ITransaction GetITransactionFromIDtcTransaction(IDtcTransaction unsafe { nint unknown = Marshal.GetIUnknownForObject(transactionNative); - Guid iid = Guids.IID_ITransaction_Guid; - if (Marshal.QueryInterface(unknown, ref iid, out IntPtr transactionNativePtr) == 0) + if (Marshal.QueryInterface(unknown, in Guids.IID_ITransaction_Guid, out IntPtr transactionNativePtr) == 0) { Marshal.Release(unknown); myTransactionNative = ComInterfaceMarshaller.ConvertToManaged((void*)transactionNativePtr)!; diff --git a/src/tests/Interop/COM/ComWrappers/API/Program.cs b/src/tests/Interop/COM/ComWrappers/API/Program.cs index fef40e8d5d0d1d..c7c4cba921fe74 100644 --- a/src/tests/Interop/COM/ComWrappers/API/Program.cs +++ b/src/tests/Interop/COM/ComWrappers/API/Program.cs @@ -86,14 +86,14 @@ protected override object CreateObject(IntPtr externalComObject, CreateObjectFla { var iTrackerObjectIid = typeof(ITrackerObject).GUID; IntPtr iTrackerComObject; - int hr = Marshal.QueryInterface(externalComObject, ref iTrackerObjectIid, out iTrackerComObject); + int hr = Marshal.QueryInterface(externalComObject, in iTrackerObjectIid, out iTrackerComObject); if (hr == 0) { return new ITrackerObjectWrapper(iTrackerComObject); } var iTestIid = typeof(ITest).GUID; IntPtr iTest; - hr = Marshal.QueryInterface(externalComObject, ref iTestIid, out iTest); + hr = Marshal.QueryInterface(externalComObject, in iTestIid, out iTest); if (hr == 0) { return new ITestObjectWrapper(iTest); @@ -320,7 +320,7 @@ unsafe static void CallSetValue(TestComWrappers wrappers, Test testInstance, int var iid = typeof(ITest).GUID; nint itestPtr; - Assert.Equal(0, Marshal.QueryInterface(nativeInstance, ref iid, out itestPtr)); + Assert.Equal(0, Marshal.QueryInterface(nativeInstance, in iid, out itestPtr)); var inst = (ComWrappers.ComInterfaceDispatch*)itestPtr; var vtbl = (ITestVtbl*)(inst->Vtable); @@ -376,7 +376,7 @@ unsafe static void CallSetValue(ComWrappers wrappers) var iid = typeof(ITest).GUID; nint itestPtr; - Assert.Equal(0, Marshal.QueryInterface(nativeInstance, ref iid, out itestPtr)); + Assert.Equal(0, Marshal.QueryInterface(nativeInstance, in iid, out itestPtr)); var inst = (ComWrappers.ComInterfaceDispatch*)itestPtr; var vtbl = (ITestVtbl*)(inst->Vtable); @@ -413,12 +413,12 @@ public void ValidateFallbackQueryInterface() IntPtr result; var anyGuid = new Guid("1E42439C-DCB5-4701-ACBD-87FE92E785DE"); testObj.ICustomQueryInterface_GetInterfaceIID = anyGuid; - int hr = Marshal.QueryInterface(comWrapper, ref anyGuid, out result); + int hr = Marshal.QueryInterface(comWrapper, in anyGuid, out result); Assert.Equal(0, hr); Assert.Equal(testObj.ICustomQueryInterface_GetInterfaceResult, result); var anyGuid2 = new Guid("7996D0F9-C8DD-4544-B708-0F75C6FF076F"); - hr = Marshal.QueryInterface(comWrapper, ref anyGuid2, out result); + hr = Marshal.QueryInterface(comWrapper, in anyGuid2, out result); const int E_NOINTERFACE = unchecked((int)0x80004002); Assert.Equal(E_NOINTERFACE, hr); Assert.Equal(IntPtr.Zero, result); @@ -507,8 +507,7 @@ public void ValidateMappingAPIs() // Create a wrapper for the unmanaged instance IntPtr unmanagedObj = MockReferenceTrackerRuntime.CreateTrackerObject(); - Guid IID_IUnknown = IUnknownVtbl.IID_IUnknown; - Assert.Equal(0, Marshal.QueryInterface(unmanagedObj, ref IID_IUnknown, out IntPtr unmanagedObjIUnknown)); + Assert.Equal(0, Marshal.QueryInterface(unmanagedObj, in IUnknownVtbl.IID_IUnknown, out IntPtr unmanagedObjIUnknown)); var unmanagedWrapper = cw.GetOrCreateObjectForComInstance(unmanagedObj, CreateObjectFlags.None); // Also allocate a unique instance to validate looking from an uncached instance @@ -598,7 +597,7 @@ public void ValidatePrecreatedExternalWrapper() // Manually create a wrapper var iid = typeof(ITrackerObject).GUID; IntPtr iTestComObject; - int hr = Marshal.QueryInterface(trackerObjRaw, ref iid, out iTestComObject); + int hr = Marshal.QueryInterface(trackerObjRaw, in iid, out iTestComObject); Assert.Equal(0, hr); var nativeWrapper = new ITrackerObjectWrapper(iTestComObject); @@ -663,7 +662,7 @@ static WeakReference CreateAndRegisterWrapper(ComWrappers // Manually create a wrapper var iid = typeof(ITrackerObject).GUID; IntPtr iTestComObject; - int hr = Marshal.QueryInterface(trackerObjRaw, ref iid, out iTestComObject); + int hr = Marshal.QueryInterface(trackerObjRaw, in iid, out iTestComObject); Assert.Equal(0, hr); var nativeWrapper = new ITrackerObjectWrapper(iTestComObject); @@ -881,7 +880,7 @@ public void ValidateQueryInterfaceAfterManagedObjectCollected() // part of the contract for a Reference Tracker runtime. var iid = typeof(ITest).GUID; IntPtr iTestComObject; - int hr = Marshal.QueryInterface(refTrackerTarget, ref iid, out iTestComObject); + int hr = Marshal.QueryInterface(refTrackerTarget, in iid, out iTestComObject); const int COR_E_ACCESSING_CCW = unchecked((int)0x80131544); Assert.Equal(COR_E_ACCESSING_CCW, hr); diff --git a/src/tests/Interop/COM/ComWrappers/Common.cs b/src/tests/Interop/COM/ComWrappers/Common.cs index 748c5f9c5c701e..fb99fb15bc33ad 100644 --- a/src/tests/Interop/COM/ComWrappers/Common.cs +++ b/src/tests/Interop/COM/ComWrappers/Common.cs @@ -61,7 +61,7 @@ CustomQueryInterfaceResult ICustomQueryInterface.GetInterface(ref Guid iid, out public struct IUnknownVtbl { - public static Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046"); + public static readonly Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046"); public IntPtr QueryInterface; public IntPtr AddRef; @@ -314,7 +314,7 @@ CustomQueryInterfaceResult ICustomQueryInterface.GetInterface(ref Guid iid, out const int S_OK = 0; const int E_NOINTERFACE = unchecked((int)0x80004002); - int hr = Marshal.QueryInterface(this.classNative.Inner, ref iid, out ppv); + int hr = Marshal.QueryInterface(this.classNative.Inner, in iid, out ppv); if (hr == S_OK) { return CustomQueryInterfaceResult.Handled; @@ -391,7 +391,7 @@ public unsafe static void Init( // it should answer immediately without going through the outer. Either way // the reference count will go to the new instance. IntPtr queryForTracker = isAggregation ? classNative.Inner : classNative.Instance; - int hr = Marshal.QueryInterface(queryForTracker, ref IID_IReferenceTracker, out classNative.ReferenceTracker); + int hr = Marshal.QueryInterface(queryForTracker, in IID_IReferenceTracker, out classNative.ReferenceTracker); if (hr != 0) { classNative.ReferenceTracker = default; diff --git a/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstance.cs b/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstance.cs index d07a0adc89c67c..f504491a723ec2 100644 --- a/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstance.cs +++ b/src/tests/Interop/COM/ComWrappers/GlobalInstance/GlobalInstance.cs @@ -160,7 +160,7 @@ protected override object CreateObject(IntPtr externalComObject, CreateObjectFla { var iid = iids[i]; IntPtr comObject; - int hr = Marshal.QueryInterface(externalComObject, ref iid, out comObject); + int hr = Marshal.QueryInterface(externalComObject, in iid, out comObject); if (hr == 0) return new FakeWrapper(comObject); } diff --git a/src/tests/Interop/DisabledRuntimeMarshalling/PInvokeAssemblyMarshallingDisabled/PInvokes.cs b/src/tests/Interop/DisabledRuntimeMarshalling/PInvokeAssemblyMarshallingDisabled/PInvokes.cs index 9ac2255fbb3b18..35664031e21beb 100644 --- a/src/tests/Interop/DisabledRuntimeMarshalling/PInvokeAssemblyMarshallingDisabled/PInvokes.cs +++ b/src/tests/Interop/DisabledRuntimeMarshalling/PInvokeAssemblyMarshallingDisabled/PInvokes.cs @@ -65,7 +65,7 @@ public static void PreserveSig_False_NotSupported() public static void Varargs_NotSupported() { AssertThrowsCorrectException(() => DisabledRuntimeMarshallingNative.CallWithVarargs(__arglist(1, 2, 3))); - + static void AssertThrowsCorrectException(Action testCode) { try @@ -104,7 +104,8 @@ public static void ByRef_Args_Not_Supported() public static void NoBooleanNormalization() { byte byteVal = 42; - Assert.Equal(byteVal, Unsafe.As(ref Unsafe.AsRef(DisabledRuntimeMarshallingNative.GetByteAsBool(byteVal)))); + bool boolVal = DisabledRuntimeMarshallingNative.GetByteAsBool(byteVal); + Assert.Equal(byteVal, Unsafe.As(ref Unsafe.AsRef(in boolVal))); } [Fact]