-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Closed
Labels
Milestone
Description
Testcase:
using System;
using System.Diagnostics;
using System.Numerics;
public class Tests
{
private interface INegator<T> where T : struct
{
static abstract bool NegateIfNeeded(bool equals);
}
private readonly struct DontNegate<T> : INegator<T> where T : struct
{
public static bool NegateIfNeeded(bool equals) => equals;
}
private readonly struct Negate<T> : INegator<T> where T : struct
{
public static bool NegateIfNeeded(bool equals) => !equals;
}
private static int IndexOfValueType<TValue, TNegator>()
where TValue : struct, INumber<TValue>
where TNegator : struct, INegator<TValue>
{
for (int j = 0; j < 1000; ++j) {
for (int i = 0; i < 100000; ++i)
TNegator.NegateIfNeeded (true);
}
return 0;
}
public static void Main () {
var w = Stopwatch.StartNew ();
IndexOfValueType<byte, DontNegate<byte>> ();
w.Stop ();
Console.WriteLine (w.ElapsedMilliseconds);
}
}
When calling IndexOfValueType<byte, DontNegate<byte>>, the AOT compiler will compile a shared instance for bytes/enums with byte basetype, but inside the shared method it can't resolve the
constrained. !!TNegator
call bool class Tests/INegator`1<!!TValue>::NegateIfNeeded(bool)
call to DontNegate so it doesn't get inlined.
This is hit with the recent BCL changes to SpanHelpers.