{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/roslyn/issues/12514","repository_url":"https://api.github.com/repos/dotnet/roslyn","labels_url":"https://api.github.com/repos/dotnet/roslyn/issues/12514/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/roslyn/issues/12514/comments","events_url":"https://api.github.com/repos/dotnet/roslyn/issues/12514/events","html_url":"https://github.com/dotnet/roslyn/issues/12514","id":165468660,"number":12514,"title":"CS0165 when using null coalesce and out parameters in if statement","user":{"login":"yaakov-h","id":426009,"avatar_url":"https://avatars.githubusercontent.com/u/426009?v=3","gravatar_id":"","url":"https://api.github.com/users/yaakov-h","html_url":"https://github.com/yaakov-h","followers_url":"https://api.github.com/users/yaakov-h/followers","following_url":"https://api.github.com/users/yaakov-h/following{/other_user}","gists_url":"https://api.github.com/users/yaakov-h/gists{/gist_id}","starred_url":"https://api.github.com/users/yaakov-h/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yaakov-h/subscriptions","organizations_url":"https://api.github.com/users/yaakov-h/orgs","repos_url":"https://api.github.com/users/yaakov-h/repos","events_url":"https://api.github.com/users/yaakov-h/events{/privacy}","received_events_url":"https://api.github.com/users/yaakov-h/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2016-07-14T03:30:42Z","updated_at":"2016-07-14T12:26:59Z","closed_at":null,"body":"**Version Used**:  Microsoft Visual Studio Enterprise 2015 Version 14.0.25421.03 Update 3\r\n\r\n**Steps to Reproduce**:\r\n\r\n1. Attempt to compile the following source code:\r\n```\r\nusing System.Collections.Generic;\r\n\r\nnamespace RoslynNullableOutReturns\r\n{\r\n\tpublic static class DictionaryExtensions\r\n\t{\r\n\t\tstatic TValue GetValueOrDefault1<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)\r\n\t\t{\r\n\t\t\tTValue value;\r\n\t\t\t\r\n\t\t\tif (dictionary?.TryGetValue(key, out value) ?? false)\r\n\t\t\t{\r\n\t\t\t\treturn value;\r\n\t\t\t}\r\n\r\n\t\t\treturn default(TValue);\r\n\t\t}\r\n\r\n\t\tstatic TValue GetValueOrDefault2<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)\r\n\t\t{\r\n\t\t\tTValue value;\r\n\r\n\t\t\tvar x = (dictionary != null) ? dictionary.TryGetValue(key, out value) : false;\r\n\t\t\tif (x)\r\n\t\t\t{\r\n\t\t\t\treturn value;\r\n\t\t\t}\r\n\r\n\t\t\treturn default(TValue);\r\n\t\t}\r\n\r\n\t\tstatic TValue GetValueOrDefault3<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)\r\n\t\t{\r\n\t\t\tTValue value;\r\n\t\t\tif (dictionary != null && dictionary.TryGetValue(key, out value))\r\n\t\t\t{\r\n\t\t\t\treturn value;\r\n\t\t\t}\r\n\r\n\t\t\treturn default(TValue);\r\n\t\t}\r\n\t}\r\n}\r\n``` \r\n\r\n**Expected Behavior**:\r\n1. `GetValueOrDefault1` should have no errors.\r\n2. `GetValueOrDefault2` could have error, could have no error. I have uncertain expectations here.\r\n3. `GetValueOrDefault3` should have no errors.\r\n\r\n**Actual Behavior**:\r\n1. `GetValueOrDefault1` has error CS0165 `Use of unassigned local variable 'value'` on line 13.\r\n2. `GetValueOrDefault2` has error CS0165 `Use of unassigned local variable 'value'` on line 26.\r\n3. `GetValueOrDefault3` has no errors.\r\n\r\n---\r\n\r\nI would expect that the compiler can understand that there is no code path that gets to `return value;` where by `TryGetValue` has not been called, since it's only dealing with that and compile-time constants.\r\n"},"comment":{"url":"https://api.github.com/repos/dotnet/roslyn/issues/comments/232651040","html_url":"https://github.com/dotnet/roslyn/issues/12514#issuecomment-232651040","issue_url":"https://api.github.com/repos/dotnet/roslyn/issues/12514","id":232651040,"user":{"login":"yaakov-h","id":426009,"avatar_url":"https://avatars.githubusercontent.com/u/426009?v=3","gravatar_id":"","url":"https://api.github.com/users/yaakov-h","html_url":"https://github.com/yaakov-h","followers_url":"https://api.github.com/users/yaakov-h/followers","following_url":"https://api.github.com/users/yaakov-h/following{/other_user}","gists_url":"https://api.github.com/users/yaakov-h/gists{/gist_id}","starred_url":"https://api.github.com/users/yaakov-h/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yaakov-h/subscriptions","organizations_url":"https://api.github.com/users/yaakov-h/orgs","repos_url":"https://api.github.com/users/yaakov-h/repos","events_url":"https://api.github.com/users/yaakov-h/events{/privacy}","received_events_url":"https://api.github.com/users/yaakov-h/received_events","type":"User","site_admin":false},"created_at":"2016-07-14T12:26:59Z","updated_at":"2016-07-14T12:26:59Z","body":"And yet I can do:\r\n\r\n```\r\nint i;\r\nif (false) {\r\n    Console.WriteLine(i); // CS0165 here\r\n}\r\n```\r\n\r\nSo when it's inline, the compiler understands the flow. When it's broken out into a variable, the compiler does not.\r\n\r\nWhich is why I had uncertain expectations for case 2, but I'd expect case 1 to compile.\r\n\r\n(Yes, I know internally the compiler breaks out a null-conditional operation into a separate variable.)"}}
{"actor":{"display_login":"yaakov-h"}}