{"action":"created","issue":{"url":"https://api.github.com/repos/rust-lang/rust/issues/22834","labels_url":"https://api.github.com/repos/rust-lang/rust/issues/22834/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rust/issues/22834/comments","events_url":"https://api.github.com/repos/rust-lang/rust/issues/22834/events","html_url":"https://github.com/rust-lang/rust/issues/22834","id":59053805,"number":22834,"title":"[E0207] thrown even though T is used in associated type","user":{"login":"Byron","id":63622,"avatar_url":"https://avatars.githubusercontent.com/u/63622?v=3","gravatar_id":"","url":"https://api.github.com/users/Byron","html_url":"https://github.com/Byron","followers_url":"https://api.github.com/users/Byron/followers","following_url":"https://api.github.com/users/Byron/following{/other_user}","gists_url":"https://api.github.com/users/Byron/gists{/gist_id}","starred_url":"https://api.github.com/users/Byron/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Byron/subscriptions","organizations_url":"https://api.github.com/users/Byron/orgs","repos_url":"https://api.github.com/users/Byron/repos","events_url":"https://api.github.com/users/Byron/events{/privacy}","received_events_url":"https://api.github.com/users/Byron/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-02-26T10:44:32Z","updated_at":"2015-02-26T11:39:46Z","closed_at":null,"body":"```Rust\r\nuse std::default::Default;\r\n\r\ntrait Maker {\r\n    type Item;\r\n\r\n    fn make(&mut self) -> Self::Item;\r\n}\r\n\r\nstruct Foo<T> {\r\n    a: T,\r\n}\r\n\r\nstruct Bar;\r\n\r\nimpl<T> Maker for Bar\r\n    where T: Default  {\r\n    type Item = Foo<T>;\r\n\r\n    fn make(&mut self) -> Foo<T> {\r\n        Foo {\r\n            a: <T as Default>::default(),\r\n        }\r\n    }\r\n}\r\n```\r\n\r\nThe code above fails to compile with error ...\r\n```\r\ntests/lang.rs:1000:10: 1000:11 error: the type parameter `T` is not constrained by the impl trait, self type, or predicates [E0207]\r\ntests/lang.rs:1000     impl<T> Maker for Bar\r\n```\r\n... even though `T` is used in the associated type `Foo`. This example looks very similar to a legal case [in the respective RFC](https://github.com/rust-lang/rfcs/blob/master/text/0447-no-unused-impl-parameters.md), namely:\r\n```Rust\r\n// Legal:\r\n// - A is used in the self type.\r\n// - B is used in the input trait type parameters.\r\nimpl<A,B> SomeTrait<Option<B>> for Foo<A> {\r\n    type Output = Result<A, IoError>;\r\n}\r\n```\r\n\r\nOne workaround is the use of `PhantomData` ...\r\n```Rust\r\nuse std::marker::PhantomData;\r\nstruct Bar<T> {\r\n    _m: PhantomData<T>\r\n}\r\n\r\nimpl<T> Maker for Bar<T>\r\n    where T: Default  {\r\n    type Item = Foo<T>;\r\n\r\n    fn make(&mut self) -> Foo<T> {\r\n        Foo {\r\n            a: <T as Default>::default(),\r\n        }\r\n    }\r\n}\r\n```\r\n... which to my mind shouldn't be required in the first place.\r\n\r\n### Meta\r\n\r\n```bash\r\n$ rustc --verbose --version\r\nrustc 1.0.0-nightly (522d09dfe 2015-02-19) (built 2015-02-19)\r\nbinary: rustc\r\ncommit-hash: 522d09dfecbeca1595f25ac58c6d0178bbd21d7d\r\ncommit-date: 2015-02-19\r\nbuild-date: 2015-02-19\r\nhost: x86_64-apple-darwin\r\nrelease: 1.0.0-nightly\r\n```"},"comment":{"url":"https://api.github.com/repos/rust-lang/rust/issues/comments/76164162","html_url":"https://github.com/rust-lang/rust/issues/22834#issuecomment-76164162","issue_url":"https://api.github.com/repos/rust-lang/rust/issues/22834","id":76164162,"user":{"login":"Kimundi","id":2903206,"avatar_url":"https://avatars.githubusercontent.com/u/2903206?v=3","gravatar_id":"","url":"https://api.github.com/users/Kimundi","html_url":"https://github.com/Kimundi","followers_url":"https://api.github.com/users/Kimundi/followers","following_url":"https://api.github.com/users/Kimundi/following{/other_user}","gists_url":"https://api.github.com/users/Kimundi/gists{/gist_id}","starred_url":"https://api.github.com/users/Kimundi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Kimundi/subscriptions","organizations_url":"https://api.github.com/users/Kimundi/orgs","repos_url":"https://api.github.com/users/Kimundi/repos","events_url":"https://api.github.com/users/Kimundi/events{/privacy}","received_events_url":"https://api.github.com/users/Kimundi/received_events","type":"User","site_admin":false},"created_at":"2015-02-26T11:39:46Z","updated_at":"2015-02-26T11:39:46Z","body":"This is intended behavior: The idea behind associated types is that they are uniqly determined by `Self` and all input type parameters. In you example and workaround, this is always the case:\r\n\r\n```rust\r\nimpl<A,B> SomeTrait<Option<B>> for Foo<A> {\r\n    type Output = Result<A, IoError>;\r\n}\r\n\r\n// Foo<A>::Output is different for each A\r\n\r\nstruct Bar<T> {\r\n    _m: PhantomData<T>\r\n}\r\n\r\n// Bar<T>::Maker is different for each T\r\n```\r\n\r\nIf you want to allow many possible types for the same `Self` type, you have to use input type parameters:\r\n\r\n```rust\r\nuse std::default::Default;\r\n\r\ntrait Maker<Item> {\r\n    fn make(&mut self) -> Item;\r\n}\r\n\r\nstruct Foo<T> {\r\n    a: T,\r\n}\r\n\r\nstruct Bar;\r\n\r\nimpl<T> Maker<Foo<T>> for Bar\r\n    where T: Default  \r\n{\r\n\r\n    fn make(&mut self) -> Foo<T> {\r\n        Foo {\r\n            a: <T as Default>::default(),\r\n        }\r\n    }\r\n}\r\n```\r\n\r\n"}}