{"action":"created","issue":{"url":"https://api.github.com/repos/xunit/xunit/issues/946","repository_url":"https://api.github.com/repos/xunit/xunit","labels_url":"https://api.github.com/repos/xunit/xunit/issues/946/labels{/name}","comments_url":"https://api.github.com/repos/xunit/xunit/issues/946/comments","events_url":"https://api.github.com/repos/xunit/xunit/issues/946/events","html_url":"https://github.com/xunit/xunit/issues/946","id":172601002,"number":946,"title":"[bug] Generic nullable type inference does not work correctly","user":{"login":"jamesqo","id":9159214,"avatar_url":"https://avatars.githubusercontent.com/u/9159214?v=3","gravatar_id":"","url":"https://api.github.com/users/jamesqo","html_url":"https://github.com/jamesqo","followers_url":"https://api.github.com/users/jamesqo/followers","following_url":"https://api.github.com/users/jamesqo/following{/other_user}","gists_url":"https://api.github.com/users/jamesqo/gists{/gist_id}","starred_url":"https://api.github.com/users/jamesqo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamesqo/subscriptions","organizations_url":"https://api.github.com/users/jamesqo/orgs","repos_url":"https://api.github.com/users/jamesqo/repos","events_url":"https://api.github.com/users/jamesqo/events{/privacy}","received_events_url":"https://api.github.com/users/jamesqo/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":6,"created_at":"2016-08-23T02:52:00Z","updated_at":"2016-09-15T07:25:33Z","closed_at":null,"body":"## Repro\r\n\r\n```cs\r\npublic class Class1\r\n{\r\n    [Theory]\r\n    [MemberData(nameof(FooData))]\r\n    public void Foo(int? nullable)\r\n    {\r\n    }\r\n\r\n    [Theory]\r\n    [MemberData(nameof(FooData))]\r\n    public void GenericFoo<T>(T? nullable) where T : struct\r\n    {\r\n        Console.WriteLine(typeof(T));\r\n    }\r\n\r\n    public static IEnumerable<object[]> FooData()\r\n    {\r\n        yield return new object[] { new int?(3) };\r\n    }\r\n}\r\n```\r\n\r\n## Expected\r\n\r\n`System.Int32` is printed to the console.\r\n\r\n## Actual\r\n\r\nxUnit recognizes `T` as `System.Object`, and since it does not match the constraint of `T :  struct` an exception is thrown.\r\n\r\n```\r\nSystem.ArgumentException : GenericArguments[0], 'System.Object', on 'Void GenericFoo[T](System.Nullable`1[T])' violates the constraint of type 'T'.\r\n ---- System.Security.VerificationException : Method BugLib2.Class1.GenericFoo: type argument 'System.Object' violates the constraint of type parameter 'T'.\r\n Stack Trace:\r\n      at System.RuntimeType.ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e)\r\n      at System.Reflection.RuntimeMethodInfo.MakeGenericMethod(Type[] methodInstantiation)\r\n   ----- Inner Stack Trace -----\r\n      at System.RuntimeMethodHandle.GetStubIfNeeded(RuntimeMethodHandleInternal method, RuntimeType declaringType, RuntimeType[] methodInstantiation)\r\n      at System.Reflection.RuntimeMethodInfo.MakeGenericMethod(Type[] methodInstantiation)\r\n```\r\n\r\nI believe this is due to the special way Nullable is handled when it is boxed/unboxed; when you box a `Nullable<T>` it actually becomes a boxed `T`, or null if it was null. For example:\r\n\r\n```cs\r\nint? nullable = 3;\r\nobject boxed = nullable;\r\nConsole.WriteLine(boxed is int); // True\r\nobject boxedNull = default(int?);\r\nConsole.WriteLine(boxedNull == null); // True\r\n```\r\n\r\nThe changed type of the boxed item is probably causing some issues with the type inference algorithms for generic theories."},"comment":{"url":"https://api.github.com/repos/xunit/xunit/issues/comments/247256019","html_url":"https://github.com/xunit/xunit/issues/946#issuecomment-247256019","issue_url":"https://api.github.com/repos/xunit/xunit/issues/946","id":247256019,"user":{"login":"hughbe","id":1275900,"avatar_url":"https://avatars.githubusercontent.com/u/1275900?v=3","gravatar_id":"","url":"https://api.github.com/users/hughbe","html_url":"https://github.com/hughbe","followers_url":"https://api.github.com/users/hughbe/followers","following_url":"https://api.github.com/users/hughbe/following{/other_user}","gists_url":"https://api.github.com/users/hughbe/gists{/gist_id}","starred_url":"https://api.github.com/users/hughbe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hughbe/subscriptions","organizations_url":"https://api.github.com/users/hughbe/orgs","repos_url":"https://api.github.com/users/hughbe/repos","events_url":"https://api.github.com/users/hughbe/events{/privacy}","received_events_url":"https://api.github.com/users/hughbe/received_events","type":"User","site_admin":false},"created_at":"2016-09-15T07:25:33Z","updated_at":"2016-09-15T07:25:33Z","body":"@bradwilson indeed, I have submitted the PR James linked. Please take a look, it's quite powerful!"}}
{"actor":{"display_login":"hughbe"}}