{"action":"created","issue":{"url":"https://api.github.com/repos/rust-lang/rust/issues/49624","repository_url":"https://api.github.com/repos/rust-lang/rust","labels_url":"https://api.github.com/repos/rust-lang/rust/issues/49624/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rust/issues/49624/comments","events_url":"https://api.github.com/repos/rust-lang/rust/issues/49624/events","html_url":"https://github.com/rust-lang/rust/pull/49624","id":310862459,"node_id":"MDExOlB1bGxSZXF1ZXN0MTc5MTE4MDE1","number":49624,"title":"#48538 Specialization: Intersection Impls","user":{"login":"giannicic","id":10560238,"node_id":"MDQ6VXNlcjEwNTYwMjM4","avatar_url":"https://avatars3.githubusercontent.com/u/10560238?v=4","gravatar_id":"","url":"https://api.github.com/users/giannicic","html_url":"https://github.com/giannicic","followers_url":"https://api.github.com/users/giannicic/followers","following_url":"https://api.github.com/users/giannicic/following{/other_user}","gists_url":"https://api.github.com/users/giannicic/gists{/gist_id}","starred_url":"https://api.github.com/users/giannicic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/giannicic/subscriptions","organizations_url":"https://api.github.com/users/giannicic/orgs","repos_url":"https://api.github.com/users/giannicic/repos","events_url":"https://api.github.com/users/giannicic/events{/privacy}","received_events_url":"https://api.github.com/users/giannicic/received_events","type":"User","site_admin":false},"labels":[{"id":583426710,"node_id":"MDU6TGFiZWw1ODM0MjY3MTA=","url":"https://api.github.com/repos/rust-lang/rust/labels/S-waiting-on-review","name":"S-waiting-on-review","color":"d3dddd","default":false},{"id":211668100,"node_id":"MDU6TGFiZWwyMTE2NjgxMDA=","url":"https://api.github.com/repos/rust-lang/rust/labels/T-compiler","name":"T-compiler","color":"bfd4f2","default":false}],"state":"open","locked":false,"assignee":{"login":"nikomatsakis","id":155238,"node_id":"MDQ6VXNlcjE1NTIzOA==","avatar_url":"https://avatars0.githubusercontent.com/u/155238?v=4","gravatar_id":"","url":"https://api.github.com/users/nikomatsakis","html_url":"https://github.com/nikomatsakis","followers_url":"https://api.github.com/users/nikomatsakis/followers","following_url":"https://api.github.com/users/nikomatsakis/following{/other_user}","gists_url":"https://api.github.com/users/nikomatsakis/gists{/gist_id}","starred_url":"https://api.github.com/users/nikomatsakis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nikomatsakis/subscriptions","organizations_url":"https://api.github.com/users/nikomatsakis/orgs","repos_url":"https://api.github.com/users/nikomatsakis/repos","events_url":"https://api.github.com/users/nikomatsakis/events{/privacy}","received_events_url":"https://api.github.com/users/nikomatsakis/received_events","type":"User","site_admin":false},"assignees":[{"login":"nikomatsakis","id":155238,"node_id":"MDQ6VXNlcjE1NTIzOA==","avatar_url":"https://avatars0.githubusercontent.com/u/155238?v=4","gravatar_id":"","url":"https://api.github.com/users/nikomatsakis","html_url":"https://github.com/nikomatsakis","followers_url":"https://api.github.com/users/nikomatsakis/followers","following_url":"https://api.github.com/users/nikomatsakis/following{/other_user}","gists_url":"https://api.github.com/users/nikomatsakis/gists{/gist_id}","starred_url":"https://api.github.com/users/nikomatsakis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nikomatsakis/subscriptions","organizations_url":"https://api.github.com/users/nikomatsakis/orgs","repos_url":"https://api.github.com/users/nikomatsakis/repos","events_url":"https://api.github.com/users/nikomatsakis/events{/privacy}","received_events_url":"https://api.github.com/users/nikomatsakis/received_events","type":"User","site_admin":false}],"milestone":null,"comments":18,"created_at":"2018-04-03T14:32:46Z","updated_at":"2018-06-18T19:36:15Z","closed_at":null,"author_association":"CONTRIBUTOR","pull_request":{"url":"https://api.github.com/repos/rust-lang/rust/pulls/49624","html_url":"https://github.com/rust-lang/rust/pull/49624","diff_url":"https://github.com/rust-lang/rust/pull/49624.diff","patch_url":"https://github.com/rust-lang/rust/pull/49624.patch"},"body":"This commit implements the Intersection Impls feature described in this [blog post](http://smallcultfollowing.com/babysteps/blog/2016/09/24/intersection-impls/).\r\n\r\n> The intuition is pretty simple: if you have two impls that have a partial intersection, but which don’t strictly subset one another, then you can add a third impl that covers precisely that intersection, and hence which subsets both of them. So now, for any type, there is always a “most specific” impl to choose.\r\n\r\nIt'a preparatory work for the implementation of the \"always applicable impls\" feature.\r\n\r\nI've some questions/doubts about the implementation:\r\n- the [check_specialization_validity](https://github.com/rust-lang/rust/blob/b12af86a776364f01f65e3bd551e2641b4fac4ec/src/librustc_typeck/check/mod.rs#L1330) method on an intersection impl should check if both parents have the default keyword? I think that at the moment it checks only the immediate parent.\r\n- should this PR include a compiler message note like the one [described here](http://smallcultfollowing.com/babysteps/blog/2016/09/24/intersection-impls/#a-note-on-compiler-messages) or we could skip it for the moment to go forward on the always applicable impls and then return at it later?\r\n\r\nr? @nikomatsakis"},"comment":{"url":"https://api.github.com/repos/rust-lang/rust/issues/comments/398170131","html_url":"https://github.com/rust-lang/rust/pull/49624#issuecomment-398170131","issue_url":"https://api.github.com/repos/rust-lang/rust/issues/49624","id":398170131,"node_id":"MDEyOklzc3VlQ29tbWVudDM5ODE3MDEzMQ==","user":{"login":"nikomatsakis","id":155238,"node_id":"MDQ6VXNlcjE1NTIzOA==","avatar_url":"https://avatars0.githubusercontent.com/u/155238?v=4","gravatar_id":"","url":"https://api.github.com/users/nikomatsakis","html_url":"https://github.com/nikomatsakis","followers_url":"https://api.github.com/users/nikomatsakis/followers","following_url":"https://api.github.com/users/nikomatsakis/following{/other_user}","gists_url":"https://api.github.com/users/nikomatsakis/gists{/gist_id}","starred_url":"https://api.github.com/users/nikomatsakis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nikomatsakis/subscriptions","organizations_url":"https://api.github.com/users/nikomatsakis/orgs","repos_url":"https://api.github.com/users/nikomatsakis/repos","events_url":"https://api.github.com/users/nikomatsakis/events{/privacy}","received_events_url":"https://api.github.com/users/nikomatsakis/received_events","type":"User","site_admin":false},"created_at":"2018-06-18T19:36:14Z","updated_at":"2018-06-18T19:36:14Z","author_association":"CONTRIBUTOR","body":"There are certainly *some* flaws in the code. For example, this part:\r\n\r\n```rust\r\nlet param_env1 = tcx.param_env(impl1);\r\n                let param_env2 = tcx.param_env(impl2);\r\n\r\n                let mut combined_param_envs_vec =\r\n                    param_env1\r\n                        .caller_bounds\r\n                        .iter()\r\n                        .chain(param_env2.caller_bounds.iter())\r\n                        .map(|p| *p)\r\n.collect::<Vec<_>>();\r\n```\r\n\r\nThose two `param_env` values are expressed in terms of disjoint sets of variables (one is expressed in terms of the variables of one impl, and one of the variables from the other), so they can't really be combined. We would have to do more careful instantiation of variables. But let's ignore those details for now.\r\n\r\nI think that the gist of what you are trying to do is to setup a chalk query where:\r\n\r\n- using the where clauses from impl A and impl B as hypotheses...\r\n- ...we try to prove the clauses from impl C\r\n\r\nI guess the premise is — if we can prove the clauses from impl C assuming only the clauses from A + B — than there must be \"no gap\", i.e., no cases uncovered. I think this is .. roughly true but we'll have to do some more sophisticated work. But actually I suspect we want to do this anyway.\r\n\r\nWe sort of want to phrase the query like\r\n\r\n```\r\nforall<A...> { // parameters from impl A\r\n  forall<B..> { // parameters from impl B\r\n    if (both impls apply) {\r\n      forall<C..> { // parameters from impl C\r\n        impl C applies\r\n      }\r\n    }\r\n  }\r\n}\r\n```\r\n\r\nBasically \"if A and B both apply, then C always applies\". That seems roughly right but the \"both impls apply\" bit is tricky. It requires being able to handle things like `if (A = B)` which -- until now -- we've avoided supporting. I think there is a way to do it that is not too bad, but I've not really worked it out in detail. We should definitely try to find a time to discuss in more detail.\r\n\r\n(Also, this condition is perhaps stricter than we want? You could imagine wanting multiple intersection impls that mutually cover the space.)"}}
{"actor":{"display_login":"nikomatsakis"}}