{"action":"created","issue":{"url":"https://api.github.com/repos/rust-lang/rust/issues/21237","labels_url":"https://api.github.com/repos/rust-lang/rust/issues/21237/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rust/issues/21237/comments","events_url":"https://api.github.com/repos/rust-lang/rust/issues/21237/events","html_url":"https://github.com/rust-lang/rust/pull/21237","id":54585764,"number":21237,"title":"Add associated types support for #[derive(...)]","user":{"login":"erickt","id":84711,"avatar_url":"https://avatars.githubusercontent.com/u/84711?v=3","gravatar_id":"","url":"https://api.github.com/users/erickt","html_url":"https://github.com/erickt","followers_url":"https://api.github.com/users/erickt/followers","following_url":"https://api.github.com/users/erickt/following{/other_user}","gists_url":"https://api.github.com/users/erickt/gists{/gist_id}","starred_url":"https://api.github.com/users/erickt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/erickt/subscriptions","organizations_url":"https://api.github.com/users/erickt/orgs","repos_url":"https://api.github.com/users/erickt/repos","events_url":"https://api.github.com/users/erickt/events{/privacy}","received_events_url":"https://api.github.com/users/erickt/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"login":"huonw","id":1203825,"avatar_url":"https://avatars.githubusercontent.com/u/1203825?v=3","gravatar_id":"","url":"https://api.github.com/users/huonw","html_url":"https://github.com/huonw","followers_url":"https://api.github.com/users/huonw/followers","following_url":"https://api.github.com/users/huonw/following{/other_user}","gists_url":"https://api.github.com/users/huonw/gists{/gist_id}","starred_url":"https://api.github.com/users/huonw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/huonw/subscriptions","organizations_url":"https://api.github.com/users/huonw/orgs","repos_url":"https://api.github.com/users/huonw/repos","events_url":"https://api.github.com/users/huonw/events{/privacy}","received_events_url":"https://api.github.com/users/huonw/received_events","type":"User","site_admin":false},"milestone":null,"comments":12,"created_at":"2015-01-16T15:14:08Z","updated_at":"2015-02-09T02:16:24Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/rust-lang/rust/pulls/21237","html_url":"https://github.com/rust-lang/rust/pull/21237","diff_url":"https://github.com/rust-lang/rust/pull/21237.diff","patch_url":"https://github.com/rust-lang/rust/pull/21237.patch"},"body":"This PR adds support for associated types to the `#[derive(...)]` syntax extension. In order to do this, it switches over to using where predicates to apply the type constraints. So now this:\r\n\r\n```rust\r\ntype Trait {\r\n    type Type;\r\n}\r\n\r\n#[derive(Clone)]\r\nstruct Foo<A> where A: Trait {\r\n    a: A,\r\n    b: <A as Trait>::Type,\r\n}\r\n```\r\n\r\nGets expended into this impl:\r\n\r\n```rust\r\nimpl<A: Clone> Clone for Foo<A> where\r\n    A: Trait,\r\n    <A as Trait>::Type: Clone,\r\n{\r\n    fn clone(&self) -> Foo<T> {\r\n        Foo {\r\n            a: self.a.clone(),\r\n            b: self.b.clone(),\r\n        }\r\n    }\r\n}\r\n```"},"comment":{"url":"https://api.github.com/repos/rust-lang/rust/issues/comments/73448283","html_url":"https://github.com/rust-lang/rust/pull/21237#issuecomment-73448283","issue_url":"https://api.github.com/repos/rust-lang/rust/issues/21237","id":73448283,"user":{"login":"erickt","id":84711,"avatar_url":"https://avatars.githubusercontent.com/u/84711?v=3","gravatar_id":"","url":"https://api.github.com/users/erickt","html_url":"https://github.com/erickt","followers_url":"https://api.github.com/users/erickt/followers","following_url":"https://api.github.com/users/erickt/following{/other_user}","gists_url":"https://api.github.com/users/erickt/gists{/gist_id}","starred_url":"https://api.github.com/users/erickt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/erickt/subscriptions","organizations_url":"https://api.github.com/users/erickt/orgs","repos_url":"https://api.github.com/users/erickt/repos","events_url":"https://api.github.com/users/erickt/events{/privacy}","received_events_url":"https://api.github.com/users/erickt/received_events","type":"User","site_admin":false},"created_at":"2015-02-09T02:16:24Z","updated_at":"2015-02-09T02:16:24Z","body":"After talking to @huonw, I feel like there isn't a great solution that works for phantom/marker types at the same time as working for an edge case of associated types. Say we extend @huonw's phantom type example from before, this time adding an associated type that's not using the trait type:\r\n\r\n```rust\r\n#[derive(Debug)]\r\nstruct Foo<T>;\r\n\r\n#[derive(Debug)]\r\nstruct Bar<T>(Foo<T>);\r\n\r\ntrait Trait { type Type; }\r\n\r\n#[derive(Debug)]\r\nstruct Baz<T: Trait>(T::Type);\r\n```\r\n\r\nWe can either generate an impl that constrains all the type parameters, which is our current approach:\r\n\r\n```rust\r\nstruct Foo<T>;\r\nimpl<T> Debug for Foo<T> where T: Debug { ... }\r\n\r\nstruct Bar<T>(Foo<T>);\r\nimpl<T> Debug for Bar<T> where T: Debug { ... }\r\n\r\ntrait Trait { type Type; }\r\n\r\nstruct Baz<T: Trait>(T::Type);\r\nimpl<T> Debug for Baz<T> where T: Debug, T::Type: Debug { ... }\r\n```\r\n\r\nNotice that the impl for `Baz` has an unnecessary `T: Debug` constraint. Or only the type parameters used in the field:\r\n\r\n```rust\r\nstruct Foo<T>;\r\nimpl<T> Debug for Foo<T> { ... }\r\n\r\nstruct Bar<T>(Foo<T>);\r\nimpl<T> Debug for Bar<T> where T: Debug { ... }\r\n\r\ntrait Trait { type Type; }\r\n\r\nstruct Baz<T: Trait>(T::Type);\r\nimpl<T> Debug for Baz<T> where T::Type: Debug { ... }\r\n```\r\n\r\nNotice that for `Bar` there is an unnecessary `T: Debug` constraint because `Foo<T>` doesn't use `T`.\r\n\r\nDoes anyone have an opinion on which approach to use, or if there are some good heuristics here to decide what to do here?"}}