runtime: Incorrect verification of type parameter constraints by CLR verifier
Probably invalid behavior of CLR verifier caused by default generic interface method while C# compiler telling that everything is OK:
static class Program
{
private interface ILogEntry
{
long Index { get; }
}
private interface IAuditTrail<TRecord>
where TRecord : class, ILogEntry
{
ValueTask AppendAsync<TRecordImpl>(TRecordImpl impl, CancellationToken token)
where TRecordImpl : notnull, TRecord => new ValueTask();
}
private interface IRaftLogEntry : ILogEntry
{
long Term { get; }
}
private sealed class AuditTrail : IAuditTrail<IRaftLogEntry>
{
}
private readonly struct EmptyLogEntry : IRaftLogEntry
{
long IRaftLogEntry.Term => 0L;
long ILogEntry.Index => 0L;
}
static void Main(string[] args)
{
IAuditTrail<IRaftLogEntry> auditTrail = new AuditTrail();
auditTrail.AppendAsync<EmptyLogEntry>(new EmptyLogEntry(), CancellationToken.None);
}
}
The exception is
System.Security.VerificationException
HResult=0x8013150D
Message=Method ConsoleApp1.Program+IAuditTrail`1[ConsoleApp1.Program+IRaftLogEntry].AppendAsync: type argument 'TRecordImpl' violates the constraint of type parameter 'TRecordImpl'.
Source=ConsoleApp1
StackTrace:
at ConsoleApp1.Program.Main(String[] args)
If implementation of AppendAsync
method moved to class instead of interface then everything is fine.
Version information:
- .NET Core version 3.1.100
- Windows 10 Enterprise 1809 64-bit
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 15 (11 by maintainers)
I ran into what I think is the same issue: here is my repro code.
`void Main() { ((IBuggy<int>)new Worky()).Foo<int>(); ((IBuggy<object>)new Worky2()).Foo<string>(); ((IBuggy<Open>)new Buggy()).Foo<Open>(); }
interface IBuggy<T1> { public void Foo<T2>() where T2 : T1 => Console.WriteLine($“Works for type: {typeof(T1)}”); } public class Worky : IBuggy<int> { } public class Worky2 : IBuggy<object> { } public class Buggy : IBuggy<Open> { } public class Open { }`
The output is: