Add asserts to catch unintentional use of generic overloads (#1200)
authorJan Kotas <jkotas@microsoft.com>
Mon, 6 Jan 2020 17:15:24 +0000 (09:15 -0800)
committerGitHub <noreply@github.com>
Mon, 6 Jan 2020 17:15:24 +0000 (09:15 -0800)
* Add asserts to catch unintentional use of generic overloads

* Delete unnecessary ifdefs

src/coreclr/src/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs
src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs
src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ValueTaskAwaiter.cs
src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs

index 0b7da5b..7c92adc 100644 (file)
@@ -4288,7 +4288,7 @@ namespace System
             }
             else
             {
-                return SpanHelpers.SequenceEqual<byte>(ref *s.m_pStringHeap, ref *m_pStringHeap, m_StringHeapByteLength);
+                return SpanHelpers.SequenceEqual(ref *s.m_pStringHeap, ref *m_pStringHeap, (uint)m_StringHeapByteLength);
             }
         }
 
index b3817d3..07f9441 100644 (file)
@@ -7,9 +7,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks.Sources;
 
-#if !NETSTANDARD2_0
 using Internal.Runtime.CompilerServices;
-#endif
 
 namespace System.Runtime.CompilerServices
 {
index d5efbd5..8791821 100644 (file)
@@ -3,9 +3,9 @@
 // See the LICENSE file in the project root for more information.
 
 using System.Diagnostics;
-#if !NETSTANDARD2_0
+using System.Runtime.CompilerServices;
+
 using Internal.Runtime.CompilerServices;
-#endif
 
 namespace System
 {
@@ -13,6 +13,9 @@ namespace System
     {
         public static int IndexOf<T>(ref T searchSpace, int searchSpaceLength, ref T value, int valueLength) where T : IEquatable<T>
         {
+            // The optimized implementation should be used for these types
+            Debug.Assert(!RuntimeHelpers.IsBitwiseEquatable<T>() || !(Unsafe.SizeOf<T>() == sizeof(byte) || Unsafe.SizeOf<T>() == sizeof(char)));
+
             Debug.Assert(searchSpaceLength >= 0);
             Debug.Assert(valueLength >= 0);
 
@@ -49,6 +52,9 @@ namespace System
         // Adapted from IndexOf(...)
         public static unsafe bool Contains<T>(ref T searchSpace, T value, int length) where T : IEquatable<T>
         {
+            // The optimized implementation should be used for these types
+            Debug.Assert(!RuntimeHelpers.IsBitwiseEquatable<T>() || !(Unsafe.SizeOf<T>() == sizeof(byte) || Unsafe.SizeOf<T>() == sizeof(char)));
+
             Debug.Assert(length >= 0);
 
             IntPtr index = (IntPtr)0; // Use IntPtr for arithmetic to avoid unnecessary 64->32->64 truncations
@@ -119,6 +125,9 @@ namespace System
 
         public static unsafe int IndexOf<T>(ref T searchSpace, T value, int length) where T : IEquatable<T>
         {
+            // The optimized implementation should be used for these types
+            Debug.Assert(!RuntimeHelpers.IsBitwiseEquatable<T>() || !(Unsafe.SizeOf<T>() == sizeof(byte) || Unsafe.SizeOf<T>() == sizeof(char)));
+
             Debug.Assert(length >= 0);
 
             IntPtr index = (IntPtr)0; // Use IntPtr for arithmetic to avoid unnecessary 64->32->64 truncations
@@ -206,6 +215,9 @@ namespace System
 
         public static int IndexOfAny<T>(ref T searchSpace, T value0, T value1, int length) where T : IEquatable<T>
         {
+            // The optimized implementation should be used for these types
+            Debug.Assert(!RuntimeHelpers.IsBitwiseEquatable<T>() || !(Unsafe.SizeOf<T>() == sizeof(byte) || Unsafe.SizeOf<T>() == sizeof(char)));
+
             Debug.Assert(length >= 0);
 
             T lookUp;
@@ -310,6 +322,9 @@ namespace System
 
         public static int IndexOfAny<T>(ref T searchSpace, T value0, T value1, T value2, int length) where T : IEquatable<T>
         {
+            // The optimized implementation should be used for these types
+            Debug.Assert(!RuntimeHelpers.IsBitwiseEquatable<T>() || !(Unsafe.SizeOf<T>() == sizeof(byte) || Unsafe.SizeOf<T>() == sizeof(char)));
+
             Debug.Assert(length >= 0);
 
             T lookUp;
@@ -413,6 +428,9 @@ namespace System
 
         public static int IndexOfAny<T>(ref T searchSpace, int searchSpaceLength, ref T value, int valueLength) where T : IEquatable<T>
         {
+            // The optimized implementation should be used for these types
+            Debug.Assert(!RuntimeHelpers.IsBitwiseEquatable<T>() || !(Unsafe.SizeOf<T>() == sizeof(byte) || Unsafe.SizeOf<T>() == sizeof(char)));
+
             Debug.Assert(searchSpaceLength >= 0);
             Debug.Assert(valueLength >= 0);
 
@@ -472,6 +490,9 @@ namespace System
 
         public static int LastIndexOf<T>(ref T searchSpace, T value, int length) where T : IEquatable<T>
         {
+            // The optimized implementation should be used for these types
+            Debug.Assert(!RuntimeHelpers.IsBitwiseEquatable<T>() || !(Unsafe.SizeOf<T>() == sizeof(byte) || Unsafe.SizeOf<T>() == sizeof(char)));
+
             Debug.Assert(length >= 0);
 
             if (default(T)! != null || (object)value != null) // TODO-NULLABLE: default(T) == null warning (https://github.com/dotnet/roslyn/issues/34757)
@@ -553,6 +574,9 @@ namespace System
 
         public static int LastIndexOfAny<T>(ref T searchSpace, T value0, T value1, int length) where T : IEquatable<T>
         {
+            // The optimized implementation should be used for these types
+            Debug.Assert(!RuntimeHelpers.IsBitwiseEquatable<T>() || !(Unsafe.SizeOf<T>() == sizeof(byte) || Unsafe.SizeOf<T>() == sizeof(char)));
+
             Debug.Assert(length >= 0);
 
             T lookUp;
@@ -656,6 +680,9 @@ namespace System
 
         public static int LastIndexOfAny<T>(ref T searchSpace, T value0, T value1, T value2, int length) where T : IEquatable<T>
         {
+            // The optimized implementation should be used for these types
+            Debug.Assert(!RuntimeHelpers.IsBitwiseEquatable<T>() || !(Unsafe.SizeOf<T>() == sizeof(byte) || Unsafe.SizeOf<T>() == sizeof(char)));
+
             Debug.Assert(length >= 0);
 
             T lookUp;
@@ -759,6 +786,9 @@ namespace System
 
         public static int LastIndexOfAny<T>(ref T searchSpace, int searchSpaceLength, ref T value, int valueLength) where T : IEquatable<T>
         {
+            // The optimized implementation should be used for these types
+            Debug.Assert(!RuntimeHelpers.IsBitwiseEquatable<T>() || !(Unsafe.SizeOf<T>() == sizeof(byte) || Unsafe.SizeOf<T>() == sizeof(char)));
+
             Debug.Assert(searchSpaceLength >= 0);
             Debug.Assert(valueLength >= 0);
 
@@ -777,6 +807,9 @@ namespace System
 
         public static bool SequenceEqual<T>(ref T first, ref T second, int length) where T : IEquatable<T>
         {
+            // The optimized implementation should be used for these types
+            Debug.Assert(!RuntimeHelpers.IsBitwiseEquatable<T>() || !(Unsafe.SizeOf<T>() == sizeof(byte) || Unsafe.SizeOf<T>() == sizeof(char)));
+
             Debug.Assert(length >= 0);
 
             if (Unsafe.AreSame(ref first, ref second))
@@ -869,6 +902,9 @@ namespace System
         public static int SequenceCompareTo<T>(ref T first, int firstLength, ref T second, int secondLength)
             where T : IComparable<T>
         {
+            // The optimized implementation should be used for these types
+            Debug.Assert(typeof(T) != typeof(byte) && typeof(T) != typeof(char));
+
             Debug.Assert(firstLength >= 0);
             Debug.Assert(secondLength >= 0);