{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/roslyn/issues/9967","repository_url":"https://api.github.com/repos/dotnet/roslyn","labels_url":"https://api.github.com/repos/dotnet/roslyn/issues/9967/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/roslyn/issues/9967/comments","events_url":"https://api.github.com/repos/dotnet/roslyn/issues/9967/events","html_url":"https://github.com/dotnet/roslyn/issues/9967","id":142738161,"number":9967,"title":"Proposal: Allow unconstrained generic type parameters to be nullable references","user":{"login":"bkoelman","id":10324372,"avatar_url":"https://avatars.githubusercontent.com/u/10324372?v=3","gravatar_id":"","url":"https://api.github.com/users/bkoelman","html_url":"https://github.com/bkoelman","followers_url":"https://api.github.com/users/bkoelman/followers","following_url":"https://api.github.com/users/bkoelman/following{/other_user}","gists_url":"https://api.github.com/users/bkoelman/gists{/gist_id}","starred_url":"https://api.github.com/users/bkoelman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bkoelman/subscriptions","organizations_url":"https://api.github.com/users/bkoelman/orgs","repos_url":"https://api.github.com/users/bkoelman/repos","events_url":"https://api.github.com/users/bkoelman/events{/privacy}","received_events_url":"https://api.github.com/users/bkoelman/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":7,"created_at":"2016-03-22T18:27:25Z","updated_at":"2016-03-22T19:35:18Z","closed_at":null,"body":"I propose to no longer issue `CS0453` on methods with the next signature in the [features/NullableReferenceTypes branch](https://github.com/dotnet/roslyn/tree/features/NullableReferenceTypes):\r\n\r\n```csharp\r\npublic static void M3<T>(T? arg) { Console.WriteLine(arg == null ? \"null\" : arg.ToString()); }\r\n```\r\n\r\nbut instead, consider the signature equivalent to:\r\n\r\n```csharp\r\npublic static void M3<T>([Nullable] T arg) { Console.WriteLine(arg == null ? \"null\" : arg.ToString()); }\r\n```\r\n\r\nwhere `[Nullable]` refers to the inaccessible compiler-builtin annotation for a nullable reference type.\r\n\r\nI believe this will not break existing code, as the construct is currently not allowed:\r\n\r\n```csharp\r\n        // CS6 + Prototype: allowed\r\n        public static void M1<T>(T arg) { Console.WriteLine(arg == null ? \"null\" : arg.ToString()); }\r\n\r\n        // CS6 + Prototype: allowed\r\n        public static void M2<T>(T? arg) where T : struct { Console.WriteLine(arg == null ? \"null\" : arg.ToString()); }\r\n\r\n        // CS6 + Prototype: allowed\r\n        public static void M3<T>(T arg) where T : class { Console.WriteLine(arg == null ? \"null\" : arg.ToString()); }\r\n\r\n        // CS6 + Prototype: CS0453\r\n        public static void M4<T>(T? arg) { Console.WriteLine(arg == null ? \"null\" : arg.ToString()); }\r\n```\r\n\r\nApplying this proposal would enable callers to pass in value types (which get boxed), nullable value types (get boxed), never-null reference types and nullable reference types.\r\n\r\nTo clarify: In this proposal, the unconstrained generic type `T?` is interpreted as `[Nullable] T`, not `Nullable<T>`.\r\n\r\nThis proposal aims to **not**:\r\n* Require changes to overload resolution (attributes are not taken into account)\r\n* Require CLR changes (this is not about unification of types)\r\n* Require changes in value type boxing (that already happens)\r\n\r\nFrom what I understand, this seems very straightforward. Without asking for alternative proposals (or potential theoretical scenarios), are there any reasons that make doing this impossible?\r\n\r\nI am aware this proposal makes it impossible to have these two overloads:\r\n```csharp\r\n        public static void M<T>(T? arg) { } // => public static void M<T>([Nullable] T arg) { }\r\n        public static void M<T>(T arg) { }\r\n```\r\nas their signatures (from a CLR perspective) are not overloads. That does not bother me, though.\r\n\r\nI would appreciate to center the discussion around the current prototype, not other directions it may or may not take in the future. Therefore, I'd kindly ask you to verify your assumptions against the actual prototype before responding. This prevents the discussion steering somewhere else, based on (incorrect) assumptions."},"comment":{"url":"https://api.github.com/repos/dotnet/roslyn/issues/comments/199979577","html_url":"https://github.com/dotnet/roslyn/issues/9967#issuecomment-199979577","issue_url":"https://api.github.com/repos/dotnet/roslyn/issues/9967","id":199979577,"user":{"login":"alrz","id":3105979,"avatar_url":"https://avatars.githubusercontent.com/u/3105979?v=3","gravatar_id":"","url":"https://api.github.com/users/alrz","html_url":"https://github.com/alrz","followers_url":"https://api.github.com/users/alrz/followers","following_url":"https://api.github.com/users/alrz/following{/other_user}","gists_url":"https://api.github.com/users/alrz/gists{/gist_id}","starred_url":"https://api.github.com/users/alrz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alrz/subscriptions","organizations_url":"https://api.github.com/users/alrz/orgs","repos_url":"https://api.github.com/users/alrz/repos","events_url":"https://api.github.com/users/alrz/events{/privacy}","received_events_url":"https://api.github.com/users/alrz/received_events","type":"User","site_admin":false},"created_at":"2016-03-22T19:35:18Z","updated_at":"2016-03-22T19:35:18Z","body":"@bkoelman If you are talking about `M3<int?>(null)` then I have no idea how `M3<T>(T arg, T? arg2)` would work."}}