Skip to content

Commit cb4a61c

Browse files
committed
Use where T : allows ref struct in runtime
1 parent 26a1e72 commit cb4a61c

File tree

32 files changed

+1114
-205
lines changed

32 files changed

+1114
-205
lines changed

src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs

+1
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ public static object GetUninitializedObject(
224224
/// <returns>true if given type is reference type or value type that contains references</returns>
225225
[Intrinsic]
226226
public static bool IsReferenceOrContainsReferences<T>()
227+
// where T : allows ref struct // TODO https://github.com/dotnet/runtime/issues/102847
227228
{
228229
// The body of this function will be replaced by the EE with unsafe code!!!
229230
// See getILIntrinsicImplementationForRuntimeHelpers for how this happens.

src/libraries/System.Collections.Concurrent/ref/System.Collections.Concurrent.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,13 @@ public ConcurrentDictionary(int concurrencyLevel, int capacity, System.Collectio
101101
public System.Collections.Generic.ICollection<TValue> Values { get { throw null; } }
102102
public TValue AddOrUpdate(TKey key, System.Func<TKey, TValue> addValueFactory, System.Func<TKey, TValue, TValue> updateValueFactory) { throw null; }
103103
public TValue AddOrUpdate(TKey key, TValue addValue, System.Func<TKey, TValue, TValue> updateValueFactory) { throw null; }
104-
public TValue AddOrUpdate<TArg>(TKey key, System.Func<TKey, TArg, TValue> addValueFactory, System.Func<TKey, TValue, TArg, TValue> updateValueFactory, TArg factoryArgument) { throw null; }
104+
public TValue AddOrUpdate<TArg>(TKey key, System.Func<TKey, TArg, TValue> addValueFactory, System.Func<TKey, TValue, TArg, TValue> updateValueFactory, TArg factoryArgument) where TArg : allows ref struct { throw null; }
105105
public void Clear() { }
106106
public bool ContainsKey(TKey key) { throw null; }
107107
public System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<TKey, TValue>> GetEnumerator() { throw null; }
108108
public TValue GetOrAdd(TKey key, System.Func<TKey, TValue> valueFactory) { throw null; }
109109
public TValue GetOrAdd(TKey key, TValue value) { throw null; }
110-
public TValue GetOrAdd<TArg>(TKey key, System.Func<TKey, TArg, TValue> valueFactory, TArg factoryArgument) { throw null; }
110+
public TValue GetOrAdd<TArg>(TKey key, System.Func<TKey, TArg, TValue> valueFactory, TArg factoryArgument) where TArg : allows ref struct { throw null; }
111111
void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>.Add(System.Collections.Generic.KeyValuePair<TKey, TValue> keyValuePair) { }
112112
bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>.Contains(System.Collections.Generic.KeyValuePair<TKey, TValue> keyValuePair) { throw null; }
113113
void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>.CopyTo(System.Collections.Generic.KeyValuePair<TKey, TValue>[] array, int index) { }

src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs

+2
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,7 @@ public TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory)
12011201
/// key is already in the dictionary, or the new value for the key as returned by valueFactory
12021202
/// if the key was not in the dictionary.</returns>
12031203
public TValue GetOrAdd<TArg>(TKey key, Func<TKey, TArg, TValue> valueFactory, TArg factoryArgument)
1204+
where TArg : allows ref struct
12041205
{
12051206
if (key is null)
12061207
{
@@ -1279,6 +1280,7 @@ public TValue GetOrAdd(TKey key, TValue value)
12791280
/// absent) or the result of updateValueFactory (if the key was present).</returns>
12801281
public TValue AddOrUpdate<TArg>(
12811282
TKey key, Func<TKey, TArg, TValue> addValueFactory, Func<TKey, TValue, TArg, TValue> updateValueFactory, TArg factoryArgument)
1283+
where TArg : allows ref struct
12821284
{
12831285
if (key is null)
12841286
{

src/libraries/System.Collections.Immutable/ref/System.Collections.Immutable.cs

+25-5
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,16 @@ public static partial class ImmutableArray
200200
public static System.Collections.Immutable.ImmutableArray<T> CreateRange<T>(System.Collections.Generic.IEnumerable<T> items) { throw null; }
201201
public static System.Collections.Immutable.ImmutableArray<TResult> CreateRange<TSource, TResult>(System.Collections.Immutable.ImmutableArray<TSource> items, System.Func<TSource, TResult> selector) { throw null; }
202202
public static System.Collections.Immutable.ImmutableArray<TResult> CreateRange<TSource, TResult>(System.Collections.Immutable.ImmutableArray<TSource> items, int start, int length, System.Func<TSource, TResult> selector) { throw null; }
203-
public static System.Collections.Immutable.ImmutableArray<TResult> CreateRange<TSource, TArg, TResult>(System.Collections.Immutable.ImmutableArray<TSource> items, System.Func<TSource, TArg, TResult> selector, TArg arg) { throw null; }
204-
public static System.Collections.Immutable.ImmutableArray<TResult> CreateRange<TSource, TArg, TResult>(System.Collections.Immutable.ImmutableArray<TSource> items, int start, int length, System.Func<TSource, TArg, TResult> selector, TArg arg) { throw null; }
203+
public static System.Collections.Immutable.ImmutableArray<TResult> CreateRange<TSource, TArg, TResult>(System.Collections.Immutable.ImmutableArray<TSource> items, System.Func<TSource, TArg, TResult> selector, TArg arg)
204+
#if NET9_0_OR_GREATER
205+
where TArg : allows ref struct
206+
#endif
207+
{ throw null; }
208+
public static System.Collections.Immutable.ImmutableArray<TResult> CreateRange<TSource, TArg, TResult>(System.Collections.Immutable.ImmutableArray<TSource> items, int start, int length, System.Func<TSource, TArg, TResult> selector, TArg arg)
209+
#if NET9_0_OR_GREATER
210+
where TArg : allows ref struct
211+
#endif
212+
{ throw null; }
205213
public static System.Collections.Immutable.ImmutableArray<T> Create<T>() { throw null; }
206214
public static System.Collections.Immutable.ImmutableArray<T> Create<T>(System.Collections.Immutable.ImmutableArray<T> items, int start, int length) { throw null; }
207215
public static System.Collections.Immutable.ImmutableArray<T> Create<T>(T item) { throw null; }
@@ -672,7 +680,11 @@ public static partial class ImmutableInterlocked
672680
public static void Enqueue<T>(ref System.Collections.Immutable.ImmutableQueue<T> location, T value) { }
673681
public static TValue GetOrAdd<TKey, TValue>(ref System.Collections.Immutable.ImmutableDictionary<TKey, TValue> location, TKey key, System.Func<TKey, TValue> valueFactory) where TKey : notnull { throw null; }
674682
public static TValue GetOrAdd<TKey, TValue>(ref System.Collections.Immutable.ImmutableDictionary<TKey, TValue> location, TKey key, TValue value) where TKey : notnull { throw null; }
675-
public static TValue GetOrAdd<TKey, TValue, TArg>(ref System.Collections.Immutable.ImmutableDictionary<TKey, TValue> location, TKey key, System.Func<TKey, TArg, TValue> valueFactory, TArg factoryArgument) where TKey : notnull { throw null; }
683+
public static TValue GetOrAdd<TKey, TValue, TArg>(ref System.Collections.Immutable.ImmutableDictionary<TKey, TValue> location, TKey key, System.Func<TKey, TArg, TValue> valueFactory, TArg factoryArgument) where TKey : notnull
684+
#if NET9_0_OR_GREATER
685+
where TArg : allows ref struct
686+
#endif
687+
{ throw null; }
676688
public static System.Collections.Immutable.ImmutableArray<T> InterlockedCompareExchange<T>(ref System.Collections.Immutable.ImmutableArray<T> location, System.Collections.Immutable.ImmutableArray<T> value, System.Collections.Immutable.ImmutableArray<T> comparand) { throw null; }
677689
public static System.Collections.Immutable.ImmutableArray<T> InterlockedExchange<T>(ref System.Collections.Immutable.ImmutableArray<T> location, System.Collections.Immutable.ImmutableArray<T> value) { throw null; }
678690
public static bool InterlockedInitialize<T>(ref System.Collections.Immutable.ImmutableArray<T> location, System.Collections.Immutable.ImmutableArray<T> value) { throw null; }
@@ -683,9 +695,17 @@ public static void Push<T>(ref System.Collections.Immutable.ImmutableStack<T> lo
683695
public static bool TryRemove<TKey, TValue>(ref System.Collections.Immutable.ImmutableDictionary<TKey, TValue> location, TKey key, [System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out TValue value) where TKey : notnull { throw null; }
684696
public static bool TryUpdate<TKey, TValue>(ref System.Collections.Immutable.ImmutableDictionary<TKey, TValue> location, TKey key, TValue newValue, TValue comparisonValue) where TKey : notnull { throw null; }
685697
public static bool Update<T>(ref T location, System.Func<T, T> transformer) where T : class? { throw null; }
686-
public static bool Update<T, TArg>(ref T location, System.Func<T, TArg, T> transformer, TArg transformerArgument) where T : class? { throw null; }
698+
public static bool Update<T, TArg>(ref T location, System.Func<T, TArg, T> transformer, TArg transformerArgument) where T : class?
699+
#if NET9_0_OR_GREATER
700+
where TArg : allows ref struct
701+
#endif
702+
{ throw null; }
687703
public static bool Update<T>(ref System.Collections.Immutable.ImmutableArray<T> location, Func<System.Collections.Immutable.ImmutableArray<T>, System.Collections.Immutable.ImmutableArray<T>> transformer) { throw null; }
688-
public static bool Update<T, TArg>(ref System.Collections.Immutable.ImmutableArray<T> location, Func<System.Collections.Immutable.ImmutableArray<T>, TArg, System.Collections.Immutable.ImmutableArray<T>> transformer, TArg transformerArgument) { throw null; }
704+
public static bool Update<T, TArg>(ref System.Collections.Immutable.ImmutableArray<T> location, Func<System.Collections.Immutable.ImmutableArray<T>, TArg, System.Collections.Immutable.ImmutableArray<T>> transformer, TArg transformerArgument)
705+
#if NET9_0_OR_GREATER
706+
where TArg : allows ref struct
707+
#endif
708+
{ throw null; }
689709
}
690710
public static partial class ImmutableList
691711
{

src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray.cs

+6
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,9 @@ public static ImmutableArray<TResult> CreateRange<TSource, TResult>(ImmutableArr
337337
/// the source array.
338338
/// </remarks>
339339
public static ImmutableArray<TResult> CreateRange<TSource, TArg, TResult>(ImmutableArray<TSource> items, Func<TSource, TArg, TResult> selector, TArg arg)
340+
#if NET9_0_OR_GREATER
341+
where TArg : allows ref struct
342+
#endif
340343
{
341344
Requires.NotNull(selector, nameof(selector));
342345

@@ -370,6 +373,9 @@ public static ImmutableArray<TResult> CreateRange<TSource, TArg, TResult>(Immuta
370373
/// included in the resulting array.
371374
/// </remarks>
372375
public static ImmutableArray<TResult> CreateRange<TSource, TArg, TResult>(ImmutableArray<TSource> items, int start, int length, Func<TSource, TArg, TResult> selector, TArg arg)
376+
#if NET9_0_OR_GREATER
377+
where TArg : allows ref struct
378+
#endif
373379
{
374380
int itemsLength = items.Length;
375381

src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableInterlocked.cs

+11-1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ public static bool Update<T>(ref T location, Func<T, T> transformer) where T : c
7676
/// invocation of <paramref name="transformer"/> returned the existing value.
7777
/// </returns>
7878
public static bool Update<T, TArg>(ref T location, Func<T, TArg, T> transformer, TArg transformerArgument) where T : class?
79+
#if NET9_0_OR_GREATER
80+
where TArg : allows ref struct
81+
#endif
7982
{
8083
Requires.NotNull(transformer, nameof(transformer));
8184

@@ -162,6 +165,9 @@ public static bool Update<T>(ref ImmutableArray<T> location, Func<ImmutableArray
162165
/// invocation of <paramref name="transformer"/> returned the existing value.
163166
/// </returns>
164167
public static bool Update<T, TArg>(ref ImmutableArray<T> location, Func<ImmutableArray<T>, TArg, ImmutableArray<T>> transformer, TArg transformerArgument)
168+
#if NET9_0_OR_GREATER
169+
where TArg : allows ref struct
170+
#endif
165171
{
166172
Requires.NotNull(transformer, nameof(transformer));
167173

@@ -241,7 +247,11 @@ public static bool InterlockedInitialize<T>(ref ImmutableArray<T> location, Immu
241247
/// <param name="valueFactory">The function to execute to obtain the value to insert into the dictionary if the key is not found.</param>
242248
/// <param name="factoryArgument">The argument to pass to the value factory.</param>
243249
/// <returns>The value obtained from the dictionary or <paramref name="valueFactory"/> if it was not present.</returns>
244-
public static TValue GetOrAdd<TKey, TValue, TArg>(ref ImmutableDictionary<TKey, TValue> location, TKey key, Func<TKey, TArg, TValue> valueFactory, TArg factoryArgument) where TKey : notnull
250+
public static TValue GetOrAdd<TKey, TValue, TArg>(ref ImmutableDictionary<TKey, TValue> location, TKey key, Func<TKey, TArg, TValue> valueFactory, TArg factoryArgument)
251+
where TKey : notnull
252+
#if NET9_0_OR_GREATER
253+
where TArg : allows ref struct
254+
#endif
245255
{
246256
Requires.NotNull(valueFactory, nameof(valueFactory));
247257

src/libraries/System.Linq/src/System/Linq/Sum.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,11 @@ private static TResult Sum<T, TResult>(ReadOnlySpan<T> span)
6060

6161
if (typeof(T) == typeof(long))
6262
{
63-
return (TResult)(object)SumSignedIntegersVectorized(MemoryMarshal.Cast<T, long>(span));
63+
return (TResult)(object)SumSignedIntegersVectorized(Unsafe.BitCast<ReadOnlySpan<T>, ReadOnlySpan<long>>(span));
6464
}
6565
if (typeof(T) == typeof(int))
6666
{
67-
return (TResult)(object)SumSignedIntegersVectorized(MemoryMarshal.Cast<T, int>(span));
67+
return (TResult)(object)SumSignedIntegersVectorized(Unsafe.BitCast<ReadOnlySpan<T>, ReadOnlySpan<int>>(span));
6868
}
6969
}
7070

src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.Helpers.cs

+8
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@ private static void ValidateInputOutputSpanNonOverlapping<T>(ReadOnlySpan<T> inp
3636
private static unsafe Span<TTo> Rename<TFrom, TTo>(Span<TFrom> span)
3737
{
3838
Debug.Assert(sizeof(TFrom) == sizeof(TTo));
39+
#if NET9_0_OR_GREATER
40+
return Unsafe.BitCast<Span<TFrom>, Span<TTo>>(span);
41+
#else
3942
return *(Span<TTo>*)(&span);
43+
#endif
4044
}
4145

4246
/// <summary>Creates a span of <typeparamref name="TTo"/> from a <typeparamref name="TFrom"/> when they're the same type.</summary>
@@ -48,7 +52,11 @@ private static unsafe Span<TTo> Rename<TFrom, TTo>(Span<TFrom> span)
4852
private static unsafe ReadOnlySpan<TTo> Rename<TFrom, TTo>(ReadOnlySpan<TFrom> span)
4953
{
5054
Debug.Assert(sizeof(TFrom) == sizeof(TTo));
55+
#if NET9_0_OR_GREATER
56+
return Unsafe.BitCast<ReadOnlySpan<TFrom>, ReadOnlySpan<TTo>>(span);
57+
#else
5158
return *(ReadOnlySpan<TTo>*)(&span);
59+
#endif
5260
}
5361

5462
/// <summary>Mask used to handle alignment elements before vectorized handling of the input.</summary>

0 commit comments

Comments
 (0)