{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/roslyn/issues/1419","labels_url":"https://api.github.com/repos/dotnet/roslyn/issues/1419/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/roslyn/issues/1419/comments","events_url":"https://api.github.com/repos/dotnet/roslyn/issues/1419/events","html_url":"https://github.com/dotnet/roslyn/issues/1419","id":63268097,"number":1419,"title":"Stronger inference of a common type of a set of expressions","user":{"login":"dsaf","id":3845650,"avatar_url":"https://avatars.githubusercontent.com/u/3845650?v=3","gravatar_id":"","url":"https://api.github.com/users/dsaf","html_url":"https://github.com/dsaf","followers_url":"https://api.github.com/users/dsaf/followers","following_url":"https://api.github.com/users/dsaf/following{/other_user}","gists_url":"https://api.github.com/users/dsaf/gists{/gist_id}","starred_url":"https://api.github.com/users/dsaf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dsaf/subscriptions","organizations_url":"https://api.github.com/users/dsaf/orgs","repos_url":"https://api.github.com/users/dsaf/repos","events_url":"https://api.github.com/users/dsaf/events{/privacy}","received_events_url":"https://api.github.com/users/dsaf/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/dotnet/roslyn/labels/2%20-%20Ready","name":"2 - Ready","color":"CCCCCC"},{"url":"https://api.github.com/repos/dotnet/roslyn/labels/Area-Language%20Design","name":"Area-Language Design","color":"5319e7"},{"url":"https://api.github.com/repos/dotnet/roslyn/labels/Feature%20Request","name":"Feature Request","color":"fc2929"}],"state":"open","locked":false,"assignee":{"login":"gafter","id":3804346,"avatar_url":"https://avatars.githubusercontent.com/u/3804346?v=3","gravatar_id":"","url":"https://api.github.com/users/gafter","html_url":"https://github.com/gafter","followers_url":"https://api.github.com/users/gafter/followers","following_url":"https://api.github.com/users/gafter/following{/other_user}","gists_url":"https://api.github.com/users/gafter/gists{/gist_id}","starred_url":"https://api.github.com/users/gafter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gafter/subscriptions","organizations_url":"https://api.github.com/users/gafter/orgs","repos_url":"https://api.github.com/users/gafter/repos","events_url":"https://api.github.com/users/gafter/events{/privacy}","received_events_url":"https://api.github.com/users/gafter/received_events","type":"User","site_admin":false},"milestone":null,"comments":24,"created_at":"2015-03-20T17:19:10Z","updated_at":"2016-01-11T20:01:22Z","closed_at":null,"body":"This code will currently not work:\r\n\r\n```csharp\r\npublic class Sample\r\n{\r\n    public static void Main()\r\n    {\r\n        //https://msdn.microsoft.com/en-us/library/bb384226.aspx\r\n        //Compiler Error CS0826: No best type found for implicitly typed array.\r\n        var animalsArray = new[] { new Dog(), new Cat() };\r\n    }\r\n}\r\n\r\npublic abstract class Animal {}\r\n\r\npublic class Dog : Animal {}\r\n\r\npublic class Cat : Animal {}\r\n```\r\n\r\nIt could go one step further and assume the first common type in the inheritance hierarchy.\r\nSeveral situations possible:\r\n\r\n1. Most straightforward - single common parent type - see above.\r\n2. Primitive types - needs explicit manual resolution.\r\n3. Nullable and non-nullable - should nullable be assumed?\r\n4. Only several common interfaces are shared - it's better to be explicit in this case rather than picking the first one.\r\n5. One common interface and a common parent type are shared - always assume the parent type, unless it's object?\r\n6. Several common interfaces and a common parent type are shared - always assume the parent type. \r\n7. Generics - probably more tricky, and a separate issue - see #1470 to start.\r\n\r\nRelated SO question: http://stackoverflow.com/questions/2799902/implicit-typing-of-arrays-that-implement-interfaces."},"comment":{"url":"https://api.github.com/repos/dotnet/roslyn/issues/comments/170672486","html_url":"https://github.com/dotnet/roslyn/issues/1419#issuecomment-170672486","issue_url":"https://api.github.com/repos/dotnet/roslyn/issues/1419","id":170672486,"user":{"login":"gafter","id":3804346,"avatar_url":"https://avatars.githubusercontent.com/u/3804346?v=3","gravatar_id":"","url":"https://api.github.com/users/gafter","html_url":"https://github.com/gafter","followers_url":"https://api.github.com/users/gafter/followers","following_url":"https://api.github.com/users/gafter/following{/other_user}","gists_url":"https://api.github.com/users/gafter/gists{/gist_id}","starred_url":"https://api.github.com/users/gafter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gafter/subscriptions","organizations_url":"https://api.github.com/users/gafter/orgs","repos_url":"https://api.github.com/users/gafter/repos","events_url":"https://api.github.com/users/gafter/events{/privacy}","received_events_url":"https://api.github.com/users/gafter/received_events","type":"User","site_admin":false},"created_at":"2016-01-11T20:01:22Z","updated_at":"2016-01-11T20:01:22Z","body":"We (the language design team) looked at this briefly last week. To summarize our understanding of the proposal, we begin with the two existing sections\r\n\r\n> ### 7.5.2.14 Finding the best common type of a set of expressions\r\n> In some cases, a common type needs to be inferred for a set of expressions. In particular, the element types of implicitly typed arrays and the return types of anonymous functions with block bodies are found in this way.\r\n>\r\nIntuitively, given a set of expressions *E1…Em* this inference should be equivalent to calling a method\r\n```cs\r\nTr M<X>(X x1 … X xm)\r\n```\r\nwith the *Ei* as arguments. \r\n> \r\nMore precisely, the inference starts out with an unfixed type variable `X`. Output type inferences are then made from each *Ei* to `X`. Finally, `X` is fixed and, if successful, the resulting type `S` is the resulting best common type for the expressions. If no such `S` exists, the expressions have no best common type.\r\n\r\nand\r\n\r\n> ### 7.5.2.11 Fixing\r\n> \r\nAn unfixed type variable `Xi` with a set of bounds is *fixed* as follows:\r\n> \r\n- The set of *candidate types* `Uj` starts out as the set of all types in the set of bounds for `Xi`.\r\n- We then examine each bound for `Xi` in turn: For each exact bound `U` of `Xi` all types `Uj` which are not identical to `U` are removed from the candidate set. For each lower bound `U` of `Xi` all types `Uj` to which there is not an implicit conversion  from `U` are removed from the candidate set. For each upper bound `U` of `Xi` all types `Uj` from which there is not an implicit conversion to `U` are removed from the candidate set.\r\n- If among the remaining candidate types `Uj` there is a unique type `V` to which there is an implicit conversion from all the other candidate types, then `Xi` is fixed to `V`.\r\n- Otherwise, type inference fails.\r\n\r\nThe proposal is to modify the penultimate bullet of 7.5.2.11 to be more generous in when it succeeds.\r\n\r\nThe LDM notes that this is a technically *incompatible* change to overload resolution. As such it is unlikely that we could accept the change as proposed. Users tend to tar and feather us if we change the meaning of existing programs, and this change would do just that. A demonstration of that fact is left to the reader.\r\n\r\nHaving said that, all is not lost. Another approach would be to leave type inference alone, and modify 7.5.2.14 to define *best common type* in terms of the desired new rule, instead of deferring to 7.5.2.11. Alternatively, we could make the desired change to the language, and provide a tool for users to migrate (or check) their code from one language version to the next, warning if there is a change in the semantic meaning of their code between language versions. Neither option is as attractive as the original proposal, presuming it were not a breaking change."}}