-
Notifications
You must be signed in to change notification settings - Fork 509
Fix direction of variance check in delegate assignment #4945
Conversation
Have you rebuilt the solution after compiling the il files? I completely agree with your changes. I think the reason why I implemented it this way around is because of how this relation is defined in ECMA:
The target method Is ECMA wrong here, or am I misunderstanding something? |
@ArztSamuel The ECMA spec does seem backwards. @VSadov @gafter FYI Thanks, I'm now able to run some tests. I have 2 failures on AccessTests though. Does that repro for you? |
Added tests :-) |
All tests should be passing. Could you specify the names of the failing tests? Edit: I think you probably didn't compile the other AccessTest assemblies (i.e. |
.method public hidebysig specialname rtspecialname | ||
instance void .ctor() cil managed | ||
{ | ||
call instance void [System.Runtime]System.Object::.ctor() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a nit, but doesn't this require the this pointer to be loaded first?
It's not really a problem, since this method is not verified anyway, but I think it is still good practice to keep the non-invalid IL code valid in these test files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, looks like I mangled it. Thanks :-)
By the way, I'd love to sync up (email or skype) at some point, so that we're not duplicating efforts. Would you mind contacting me (jcouv@microsoft.com)? Cheers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I'll send you a message.
@@ -1003,12 +1003,12 @@ bool IsDelegateAssignable(MethodDesc ftn, TypeDesc delegateType) | |||
|
|||
for (int i = 0; i < ftnSignature.Length; i++) | |||
{ | |||
if (!IsAssignable(ftnSignature[i], delegateSignature[i])) | |||
if (!IsAssignable(delegateSignature[i], ftnSignature[i])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically the types should be "Compatible". In the spec "Compatible" is more strict than "Assignable", since "Assignable" allows some reinterpretations. I.E. an int32
is Assignable to int8
- one can be assigned to another with implicit value truncation.
However int32
and int8
are not "Compatible" and therefore int M1()
cannot be used as Func<byte>
I am not sure what IsAssignable
implements. It could as well implement "IsCompatible", then everything is correct.
Perhaps it is worth adding a test while touching this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am sorry - I have not noticed that you have commented on this before merging. I agree it would be nice to add test for this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Filed follow-up issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would not block merging on this. Just a good thing to have.
The ECMA spec indeed has a bug in delegate-assignable-to definition. |
* Fix direction of variance check in delegate assignment * Add tests
I found this problem while debugging the integration of ILVerify into Roslyn. I copied the involved C# code below, but essentially, the usage of delegate returned by
Bar
(which is aFunc<int, string>
) in aFunc<int, object>
.ILVerify previously thought that is illegal because it treated the return type
string
as the destination andobject
as the source for an assignment. But, actually,string
is the source, andobject
is the destination.The arguments are also in the wrong order (although in the other order).
I'm happy to add a unittest, but was unable to run tests so far.
In Test Explorer, I get
Message: System.InvalidOperationException : No data found for ILVerify.Tests.ILMethodTester.TestMethodsWithInvalidIL
.I've compiled some IL files in
repos\corert\src\ILVerify\tests\ILTests
(for example, withilasm AccessTests.il /dll /ERROR
), but the test runner doesn't detect the resulting assembly somehow. Not debugged yet.Also, I'm setting the project to target AnyCPU, which helps for integration with Roslyn.
Tagging @jkotas @ArztSamuel @VSadov